@@ -80,7 +80,7 @@ define i32 @test_inbounds_nuw_trunc(ptr %base, i64 %idx) {
8080
8181define i64 @test_inbounds_nuw_swapped (ptr %base , i64 %idx ) {
8282; CHECK-LABEL: @test_inbounds_nuw_swapped(
83- ; CHECK-NEXT: [[P2_IDX_NEG:%.*]] = mul i64 [[IDX:%.*]], -4
83+ ; CHECK-NEXT: [[P2_IDX_NEG:%.*]] = mul nsw i64 [[IDX:%.*]], -4
8484; CHECK-NEXT: ret i64 [[P2_IDX_NEG]]
8585;
8686 %p2 = getelementptr inbounds [0 x i32 ], ptr %base , i64 0 , i64 %idx
@@ -104,7 +104,7 @@ define i64 @test_inbounds1_nuw_swapped(ptr %base, i64 %idx) {
104104
105105define i64 @test_inbounds2_nuw_swapped (ptr %base , i64 %idx ) {
106106; CHECK-LABEL: @test_inbounds2_nuw_swapped(
107- ; CHECK-NEXT: [[P2_IDX_NEG:%.*]] = mul i64 [[IDX:%.*]], -4
107+ ; CHECK-NEXT: [[P2_IDX_NEG:%.*]] = mul nsw i64 [[IDX:%.*]], -4
108108; CHECK-NEXT: ret i64 [[P2_IDX_NEG]]
109109;
110110 %p2 = getelementptr inbounds [0 x i32 ], ptr %base , i64 0 , i64 %idx
@@ -279,8 +279,8 @@ define i16 @test24_as1(ptr addrspace(1) %P, i16 %A) {
279279
280280define i64 @test24a (ptr %P , i64 %A ){
281281; CHECK-LABEL: @test24a(
282- ; CHECK-NEXT: [[DIFF_NEG :%.*]] = sub i64 0, [[A:%.*]]
283- ; CHECK-NEXT: ret i64 [[DIFF_NEG ]]
282+ ; CHECK-NEXT: [[GEPDIFF :%.*]] = sub nsw i64 0, [[A:%.*]]
283+ ; CHECK-NEXT: ret i64 [[GEPDIFF ]]
284284;
285285 %B = getelementptr inbounds i8 , ptr %P , i64 %A
286286 %C = ptrtoint ptr %B to i64
@@ -291,8 +291,8 @@ define i64 @test24a(ptr %P, i64 %A){
291291
292292define i16 @test24a_as1 (ptr addrspace (1 ) %P , i16 %A ) {
293293; CHECK-LABEL: @test24a_as1(
294- ; CHECK-NEXT: [[DIFF_NEG :%.*]] = sub i16 0, [[A:%.*]]
295- ; CHECK-NEXT: ret i16 [[DIFF_NEG ]]
294+ ; CHECK-NEXT: [[GEPDIFF :%.*]] = sub nsw i16 0, [[A:%.*]]
295+ ; CHECK-NEXT: ret i16 [[GEPDIFF ]]
296296;
297297 %B = getelementptr inbounds i8 , ptr addrspace (1 ) %P , i16 %A
298298 %C = ptrtoint ptr addrspace (1 ) %B to i16
@@ -860,3 +860,85 @@ _Z3fooPKc.exit:
860860 %tobool = icmp eq i64 %2 , 0
861861 ret i1 %tobool
862862}
863+
864+ define i64 @multiple_geps_one_chain (ptr %base , i64 %idx , i64 %idx2 ) {
865+ ; CHECK-LABEL: @multiple_geps_one_chain(
866+ ; CHECK-NEXT: [[P2_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
867+ ; CHECK-NEXT: [[D:%.*]] = shl i64 [[P2_IDX1]], 2
868+ ; CHECK-NEXT: ret i64 [[D]]
869+ ;
870+ %p2 = getelementptr inbounds i32 , ptr %base , i64 %idx
871+ %p3 = getelementptr inbounds i32 , ptr %p2 , i64 %idx2
872+ %i1 = ptrtoint ptr %base to i64
873+ %i2 = ptrtoint ptr %p3 to i64
874+ %d = sub i64 %i2 , %i1
875+ ret i64 %d
876+ }
877+
878+ define i64 @multiple_geps_one_chain_commuted (ptr %base , i64 %idx , i64 %idx2 ) {
879+ ; CHECK-LABEL: @multiple_geps_one_chain_commuted(
880+ ; CHECK-NEXT: [[P2_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
881+ ; CHECK-NEXT: [[DOTNEG:%.*]] = mul i64 [[P2_IDX1]], -4
882+ ; CHECK-NEXT: ret i64 [[DOTNEG]]
883+ ;
884+ %p2 = getelementptr inbounds i32 , ptr %base , i64 %idx
885+ %p3 = getelementptr inbounds i32 , ptr %p2 , i64 %idx2
886+ %i1 = ptrtoint ptr %base to i64
887+ %i2 = ptrtoint ptr %p3 to i64
888+ %d = sub i64 %i1 , %i2
889+ ret i64 %d
890+ }
891+
892+ define i64 @multiple_geps_two_chains (ptr %base , i64 %idx , i64 %idx2 , i64 %idx3 ) {
893+ ; CHECK-LABEL: @multiple_geps_two_chains(
894+ ; CHECK-NEXT: [[P2_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
895+ ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[P2_IDX1]], [[IDX3:%.*]]
896+ ; CHECK-NEXT: [[GEPDIFF:%.*]] = shl i64 [[TMP1]], 2
897+ ; CHECK-NEXT: ret i64 [[GEPDIFF]]
898+ ;
899+ %p2 = getelementptr inbounds i32 , ptr %base , i64 %idx
900+ %p3 = getelementptr inbounds i32 , ptr %p2 , i64 %idx2
901+ %p4 = getelementptr inbounds i32 , ptr %base , i64 %idx3
902+ %i1 = ptrtoint ptr %p4 to i64
903+ %i2 = ptrtoint ptr %p3 to i64
904+ %d = sub i64 %i2 , %i1
905+ ret i64 %d
906+ }
907+
908+ define i64 @multiple_geps_two_chains_commuted (ptr %base , i64 %idx , i64 %idx2 , i64 %idx3 ) {
909+ ; CHECK-LABEL: @multiple_geps_two_chains_commuted(
910+ ; CHECK-NEXT: [[P2_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
911+ ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[IDX3:%.*]], [[P2_IDX1]]
912+ ; CHECK-NEXT: [[GEPDIFF:%.*]] = shl i64 [[TMP1]], 2
913+ ; CHECK-NEXT: ret i64 [[GEPDIFF]]
914+ ;
915+ %p2 = getelementptr inbounds i32 , ptr %base , i64 %idx
916+ %p3 = getelementptr inbounds i32 , ptr %p2 , i64 %idx2
917+ %p4 = getelementptr inbounds i32 , ptr %base , i64 %idx3
918+ %i1 = ptrtoint ptr %p4 to i64
919+ %i2 = ptrtoint ptr %p3 to i64
920+ %d = sub i64 %i1 , %i2
921+ ret i64 %d
922+ }
923+
924+ declare void @use (ptr )
925+
926+ define i64 @multiple_geps_two_chains_gep_base (ptr %base , i64 %base.idx , i64 %idx , i64 %idx2 , i64 %idx3 ) {
927+ ; CHECK-LABEL: @multiple_geps_two_chains_gep_base(
928+ ; CHECK-NEXT: [[GEP_BASE:%.*]] = getelementptr inbounds i32, ptr [[BASE:%.*]], i64 [[BASE_IDX:%.*]]
929+ ; CHECK-NEXT: call void @use(ptr [[GEP_BASE]])
930+ ; CHECK-NEXT: [[P2_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
931+ ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[P2_IDX1]], [[IDX3:%.*]]
932+ ; CHECK-NEXT: [[GEPDIFF:%.*]] = shl i64 [[TMP1]], 2
933+ ; CHECK-NEXT: ret i64 [[GEPDIFF]]
934+ ;
935+ %gep.base = getelementptr inbounds i32 , ptr %base , i64 %base.idx
936+ call void @use (ptr %gep.base )
937+ %p2 = getelementptr inbounds i32 , ptr %gep.base , i64 %idx
938+ %p3 = getelementptr inbounds i32 , ptr %p2 , i64 %idx2
939+ %p4 = getelementptr inbounds i32 , ptr %gep.base , i64 %idx3
940+ %i1 = ptrtoint ptr %p4 to i64
941+ %i2 = ptrtoint ptr %p3 to i64
942+ %d = sub i64 %i2 , %i1
943+ ret i64 %d
944+ }
0 commit comments