@@ -80,7 +80,7 @@ define i32 @test_inbounds_nuw_trunc(ptr %base, i64 %idx) {
80
80
81
81
define i64 @test_inbounds_nuw_swapped (ptr %base , i64 %idx ) {
82
82
; 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
84
84
; CHECK-NEXT: ret i64 [[P2_IDX_NEG]]
85
85
;
86
86
%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) {
104
104
105
105
define i64 @test_inbounds2_nuw_swapped (ptr %base , i64 %idx ) {
106
106
; 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
108
108
; CHECK-NEXT: ret i64 [[P2_IDX_NEG]]
109
109
;
110
110
%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) {
279
279
280
280
define i64 @test24a (ptr %P , i64 %A ){
281
281
; 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 ]]
284
284
;
285
285
%B = getelementptr inbounds i8 , ptr %P , i64 %A
286
286
%C = ptrtoint ptr %B to i64
@@ -291,8 +291,8 @@ define i64 @test24a(ptr %P, i64 %A){
291
291
292
292
define i16 @test24a_as1 (ptr addrspace (1 ) %P , i16 %A ) {
293
293
; 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 ]]
296
296
;
297
297
%B = getelementptr inbounds i8 , ptr addrspace (1 ) %P , i16 %A
298
298
%C = ptrtoint ptr addrspace (1 ) %B to i16
@@ -860,3 +860,85 @@ _Z3fooPKc.exit:
860
860
%tobool = icmp eq i64 %2 , 0
861
861
ret i1 %tobool
862
862
}
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