@@ -849,3 +849,135 @@ 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: [[GEP3_IDX:%.*]] = shl i64 [[IDX3:%.*]], 2
856+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2:%.*]], i64 [[GEP3_IDX]]
857+ ; CHECK-NEXT: call void @use(ptr [[GEP3]])
858+ ; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl i64 [[IDX2:%.*]], 2
859+ ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i8, ptr [[GEP3]], i64 [[GEP2_IDX]]
860+ ; CHECK-NEXT: call void @use(ptr [[GEP4]])
861+ ; CHECK-NEXT: [[GEP3_IDX1:%.*]] = shl i64 [[IDX4:%.*]], 2
862+ ; CHECK-NEXT: [[GEP5:%.*]] = getelementptr i8, ptr [[GEP4]], i64 [[GEP3_IDX1]]
863+ ; CHECK-NEXT: call void @use(ptr [[GEP5]])
864+ ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[GEP3_IDX]], [[GEP2_IDX]]
865+ ; CHECK-NEXT: [[TMP2:%.*]] = sub i64 0, [[GEP3_IDX1]]
866+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], [[TMP2]]
867+ ; CHECK-NEXT: ret i1 [[CMP]]
868+ ;
869+ %gep1 = getelementptr i32 , ptr %base , i64 %idx1
870+ call void @use (ptr %gep1 )
871+ %gep2 = getelementptr i32 , ptr %gep1 , i64 %idx2
872+ call void @use (ptr %gep2 )
873+ %gep3 = getelementptr i32 , ptr %gep2 , i64 %idx3
874+ call void @use (ptr %gep3 )
875+ %cmp = icmp eq ptr %gep3 , %base
876+ ret i1 %cmp
877+ }
878+
879+ define i1 @gep_multiple_multi_use_below_limit_extra_one_use_gep1 (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
880+ ; CHECK-LABEL: @gep_multiple_multi_use_below_limit_extra_one_use_gep1(
881+ ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl i64 [[IDX1:%.*]], 2
882+ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 [[GEP1_IDX]]
883+ ; CHECK-NEXT: call void @use(ptr [[GEP1]])
884+ ; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl i64 [[IDX2:%.*]], 2
885+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[GEP1]], i64 [[GEP2_IDX]]
886+ ; CHECK-NEXT: call void @use(ptr [[GEP2]])
887+ ; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl i64 [[IDX3:%.*]], 2
888+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 [[GEP3_IDX]]
889+ ; CHECK-NEXT: call void @use(ptr [[GEP3]])
890+ ; CHECK-NEXT: [[GEP4_IDX_NEG:%.*]] = mul i64 [[IDX4:%.*]], -4
891+ ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[GEP1_IDX]], [[GEP2_IDX]]
892+ ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[GEP3_IDX]]
893+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP2]], [[GEP4_IDX_NEG]]
894+ ; CHECK-NEXT: ret i1 [[CMP]]
895+ ;
896+ %gep1 = getelementptr i32 , ptr %base , i64 %idx1
897+ call void @use (ptr %gep1 )
898+ %gep2 = getelementptr i32 , ptr %gep1 , i64 %idx2
899+ call void @use (ptr %gep2 )
900+ %gep3 = getelementptr i32 , ptr %gep2 , i64 %idx3
901+ call void @use (ptr %gep3 )
902+ %gep4 = getelementptr i32 , ptr %gep3 , i64 %idx4
903+ %cmp = icmp eq ptr %gep4 , %base
904+ ret i1 %cmp
905+ }
906+
907+ define i1 @gep_multiple_multi_use_below_limit_extra_one_use_gep2 (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
908+ ; CHECK-LABEL: @gep_multiple_multi_use_below_limit_extra_one_use_gep2(
909+ ; CHECK-NEXT: [[GEP1_IDX1:%.*]] = add i64 [[IDX1:%.*]], [[IDX2:%.*]]
910+ ; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[GEP1_IDX1]], 2
911+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 [[TMP1]]
912+ ; CHECK-NEXT: call void @use(ptr [[GEP2]])
913+ ; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl i64 [[IDX3:%.*]], 2
914+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 [[GEP3_IDX]]
915+ ; CHECK-NEXT: call void @use(ptr [[GEP3]])
916+ ; CHECK-NEXT: [[GEP4_IDX:%.*]] = shl i64 [[IDX4:%.*]], 2
917+ ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i8, ptr [[GEP3]], i64 [[GEP4_IDX]]
918+ ; CHECK-NEXT: call void @use(ptr [[GEP4]])
919+ ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[GEP3_IDX]]
920+ ; CHECK-NEXT: [[GEP4_IDX_NEG:%.*]] = sub i64 0, [[GEP4_IDX]]
921+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP2]], [[GEP4_IDX_NEG]]
922+ ; CHECK-NEXT: ret i1 [[CMP]]
923+ ;
924+ %gep1 = getelementptr i32 , ptr %base , i64 %idx1
925+ %gep2 = getelementptr i32 , ptr %gep1 , i64 %idx2
926+ call void @use (ptr %gep2 )
927+ %gep3 = getelementptr i32 , ptr %gep2 , i64 %idx3
928+ call void @use (ptr %gep3 )
929+ %gep4 = getelementptr i32 , ptr %gep3 , i64 %idx4
930+ call void @use (ptr %gep4 )
931+ %cmp = icmp eq ptr %gep4 , %base
932+ ret i1 %cmp
933+ }
934+
935+ define i1 @gep_multiple_multi_above_below_limit_consts (ptr %base , i64 %idx1 , i64 %idx2 ) {
936+ ; CHECK-LABEL: @gep_multiple_multi_above_below_limit_consts(
937+ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 16
938+ ; CHECK-NEXT: call void @use(ptr [[GEP1]])
939+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr [[GEP1]], i64 [[IDX1:%.*]]
940+ ; CHECK-NEXT: call void @use(ptr [[GEP2]])
941+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 16
942+ ; CHECK-NEXT: call void @use(ptr [[GEP3]])
943+ ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i32, ptr [[GEP3]], i64 [[IDX2:%.*]]
944+ ; CHECK-NEXT: call void @use(ptr [[GEP4]])
945+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP4]], [[BASE]]
946+ ; CHECK-NEXT: ret i1 [[CMP]]
947+ ;
948+ %gep1 = getelementptr i32 , ptr %base , i64 4
949+ call void @use (ptr %gep1 )
950+ %gep2 = getelementptr i32 , ptr %gep1 , i64 %idx1
951+ call void @use (ptr %gep2 )
952+ %gep3 = getelementptr i32 , ptr %gep2 , i64 4
953+ call void @use (ptr %gep3 )
954+ %gep4 = getelementptr i32 , ptr %gep3 , i64 %idx2
955+ call void @use (ptr %gep4 )
956+ %cmp = icmp eq ptr %gep4 , %base
957+ ret i1 %cmp
958+ }
959+
960+ define i1 @gep_multiple_multi_use_above_limit (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
961+ ; CHECK-LABEL: @gep_multiple_multi_use_above_limit(
962+ ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i32, ptr [[BASE:%.*]], i64 [[IDX1:%.*]]
963+ ; CHECK-NEXT: call void @use(ptr [[GEP4]])
964+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i32, ptr [[GEP4]], i64 [[IDX2:%.*]]
965+ ; CHECK-NEXT: call void @use(ptr [[GEP3]])
966+ ; CHECK-NEXT: [[GEP5:%.*]] = getelementptr i32, ptr [[GEP3]], i64 [[IDX3:%.*]]
967+ ; CHECK-NEXT: call void @use(ptr [[GEP5]])
968+ ; CHECK-NEXT: [[GEP6:%.*]] = getelementptr i32, ptr [[GEP5]], i64 [[IDX4:%.*]]
969+ ; CHECK-NEXT: call void @use(ptr [[GEP6]])
970+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP6]], [[BASE]]
971+ ; CHECK-NEXT: ret i1 [[CMP]]
972+ ;
973+ %gep1 = getelementptr i32 , ptr %base , i64 %idx1
974+ call void @use (ptr %gep1 )
975+ %gep2 = getelementptr i32 , ptr %gep1 , i64 %idx2
976+ call void @use (ptr %gep2 )
977+ %gep3 = getelementptr i32 , ptr %gep2 , i64 %idx3
978+ call void @use (ptr %gep3 )
979+ %gep4 = getelementptr i32 , ptr %gep3 , i64 %idx4
980+ call void @use (ptr %gep4 )
981+ %cmp = icmp eq ptr %gep4 , %base
982+ ret i1 %cmp
983+ }
0 commit comments