@@ -849,3 +849,91 @@ define i1 @gep_mugtiple_ugt_inbounds_nusw(ptr %base, i64 %idx, i64 %idx2) {
849849 %cmp = icmp ugt ptr %gep2 , %base
850850 ret i1 %cmp
851851}
852+
853+ define i1 @gep_multiple_multi_use_below_limit (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 ) {
854+ ; CHECK-LABEL: @gep_multiple_multi_use_below_limit(
855+ ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl i64 [[IDX1:%.*]], 2
856+ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 [[GEP1_IDX]]
857+ ; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl i64 [[IDX2:%.*]], 2
858+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[GEP1]], i64 [[GEP2_IDX]]
859+ ; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl i64 [[IDX3:%.*]], 2
860+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 [[GEP3_IDX]]
861+ ; CHECK-NEXT: call void @use(ptr [[GEP3]])
862+ ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[GEP1_IDX]], [[GEP2_IDX]]
863+ ; CHECK-NEXT: [[TMP2:%.*]] = sub i64 0, [[GEP3_IDX]]
864+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], [[TMP2]]
865+ ; CHECK-NEXT: ret i1 [[CMP]]
866+ ;
867+ %gep1 = getelementptr i32 , ptr %base , i64 %idx1
868+ %gep2 = getelementptr i32 , ptr %gep1 , i64 %idx2
869+ %gep3 = getelementptr i32 , ptr %gep2 , i64 %idx3
870+ call void @use (ptr %gep3 )
871+ %cmp = icmp eq ptr %gep3 , %base
872+ ret i1 %cmp
873+ }
874+
875+ define i1 @gep_multiple_multi_use_below_limit_extra_one_use_gep (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
876+ ; CHECK-LABEL: @gep_multiple_multi_use_below_limit_extra_one_use_gep(
877+ ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl i64 [[IDX1:%.*]], 2
878+ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 [[GEP1_IDX]]
879+ ; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl i64 [[IDX2:%.*]], 2
880+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[GEP1]], i64 [[GEP2_IDX]]
881+ ; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl i64 [[IDX3:%.*]], 2
882+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 [[GEP3_IDX]]
883+ ; CHECK-NEXT: [[GEP4_IDX_NEG:%.*]] = mul i64 [[IDX4:%.*]], -4
884+ ; CHECK-NEXT: call void @use(ptr [[GEP3]])
885+ ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[GEP1_IDX]], [[GEP2_IDX]]
886+ ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[GEP3_IDX]]
887+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP2]], [[GEP4_IDX_NEG]]
888+ ; CHECK-NEXT: ret i1 [[CMP]]
889+ ;
890+ %gep1 = getelementptr i32 , ptr %base , i64 %idx1
891+ %gep2 = getelementptr i32 , ptr %gep1 , i64 %idx2
892+ %gep3 = getelementptr i32 , ptr %gep2 , i64 %idx3
893+ %gep4 = getelementptr i32 , ptr %gep3 , i64 %idx4
894+ call void @use (ptr %gep3 )
895+ %cmp = icmp eq ptr %gep4 , %base
896+ ret i1 %cmp
897+ }
898+
899+ define i1 @gep_multiple_multi_use_below_limit_consts (ptr %base , i64 %idx1 , i64 %idx2 ) {
900+ ; CHECK-LABEL: @gep_multiple_multi_use_below_limit_consts(
901+ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 16
902+ ; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl i64 [[IDX1:%.*]], 2
903+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[GEP1]], i64 [[GEP2_IDX]]
904+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 16
905+ ; CHECK-NEXT: [[GEP4_IDX:%.*]] = shl i64 [[IDX2:%.*]], 2
906+ ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i8, ptr [[GEP3]], i64 [[GEP4_IDX]]
907+ ; CHECK-NEXT: call void @use(ptr [[GEP4]])
908+ ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[GEP2_IDX]], 32
909+ ; CHECK-NEXT: [[TMP2:%.*]] = sub i64 0, [[GEP4_IDX]]
910+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], [[TMP2]]
911+ ; CHECK-NEXT: ret i1 [[CMP]]
912+ ;
913+ %gep1 = getelementptr i32 , ptr %base , i64 4
914+ %gep2 = getelementptr i32 , ptr %gep1 , i64 %idx1
915+ %gep3 = getelementptr i32 , ptr %gep2 , i64 4
916+ %gep4 = getelementptr i32 , ptr %gep3 , i64 %idx2
917+ call void @use (ptr %gep4 )
918+ %cmp = icmp eq ptr %gep4 , %base
919+ ret i1 %cmp
920+ }
921+
922+ define i1 @gep_multiple_multi_use_above_limit (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
923+ ; CHECK-LABEL: @gep_multiple_multi_use_above_limit(
924+ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr [[BASE:%.*]], i64 [[IDX1:%.*]]
925+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr [[GEP1]], i64 [[IDX2:%.*]]
926+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i32, ptr [[GEP2]], i64 [[IDX3:%.*]]
927+ ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i32, ptr [[GEP3]], i64 [[IDX4:%.*]]
928+ ; CHECK-NEXT: call void @use(ptr [[GEP4]])
929+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP4]], [[BASE]]
930+ ; CHECK-NEXT: ret i1 [[CMP]]
931+ ;
932+ %gep1 = getelementptr i32 , ptr %base , i64 %idx1
933+ %gep2 = getelementptr i32 , ptr %gep1 , i64 %idx2
934+ %gep3 = getelementptr i32 , ptr %gep2 , i64 %idx3
935+ %gep4 = getelementptr i32 , ptr %gep3 , i64 %idx4
936+ call void @use (ptr %gep4 )
937+ %cmp = icmp eq ptr %gep4 , %base
938+ ret i1 %cmp
939+ }
0 commit comments