brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.9 KiB · 8a4898a Raw
260 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; Constant-indexed GEP instructions in a chain of GEP instructions should be5; swapped to the end whenever such transformation is valid. This allows them to6; be merged.7 8declare void @use(i1)9 10 11; The constant-indexed GEP instruction should be swapped to the end, even12; without merging.13; result = (((ptr) p + a) + b) + 114define ptr @basic(ptr %p, i64 %a, i64 %b) {15; CHECK-LABEL: @basic(16; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P:%.*]], i64 417; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 [[A:%.*]]18; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i64 [[B:%.*]]19; CHECK-NEXT:    ret ptr [[TMP3]]20;21  %1 = getelementptr inbounds i32, ptr %p, i64 122  %2 = getelementptr inbounds i32, ptr %1, i64 %a23  %3 = getelementptr inbounds i32, ptr %2, i64 %b24  ret ptr %325}26 27; GEP with the last index being a constant should also be swapped.28define ptr @partialConstant1(ptr %p, i64 %a, i64 %b) {29; CHECK-LABEL: @partialConstant1(30; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[B:%.*]]31; CHECK-NEXT:    ret ptr [[TMP1]]32;33  %1 = getelementptr inbounds [4 x i32], ptr %p, i64 %a, i64 134  %2 = getelementptr inbounds i32, ptr %p, i64 %b35  ret ptr %236}37 38; Negative test. GEP should not be swapped if the last index is not a constant.39define ptr @partialConstant2(ptr %p, i64 %a, i64 %b) {40; CHECK-LABEL: @partialConstant2(41; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[B:%.*]]42; CHECK-NEXT:    ret ptr [[TMP1]]43;44  %1 = getelementptr inbounds [4 x i32], ptr %p, i64 1, i64 %a45  %2 = getelementptr inbounds i32, ptr %p, i64 %b46  ret ptr %247}48 49; Constant-indexed GEP are merged after swawpping.50; result = ((ptr) p + a) + 351define ptr @merge(ptr %p, i64 %a) {52; CHECK-LABEL: @merge(53; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[A:%.*]]54; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i64 1255; CHECK-NEXT:    ret ptr [[TMP2]]56;57  %1 = getelementptr inbounds i32, ptr %p, i64 158  %2 = getelementptr inbounds i32, ptr %1, i64 %a59  %3 = getelementptr inbounds i32, ptr %2, i64 260  ret ptr %361}62 63; Multiple constant-indexed GEP. Note that the first two cannot be merged at64; first, but after the second and third are merged, the result can be merged65; with the first one on the next pass.66; result = (ptr) ((ptr) ((ptr) ptr + a) + (a * b)) + 967define ptr @nested(ptr %p, i64 %a, i64 %b) {68; CHECK-LABEL: @nested(69; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[A:%.*]]70; CHECK-NEXT:    [[TMP2:%.*]] = mul i64 [[A]], [[B:%.*]]71; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr i16, ptr [[TMP1]], i64 [[TMP2]]72; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr i8, ptr [[TMP3]], i64 16073; CHECK-NEXT:    ret ptr [[TMP4]]74;75  %1 = getelementptr inbounds <3 x i32>, ptr %p, i64 176  %2 = getelementptr inbounds i8, ptr %1, i64 %a77  %3 = mul i64 %a, %b78  %4 = getelementptr inbounds <5 x i32>, ptr %2, i64 479  %5 = getelementptr inbounds i16, ptr %4, i64 %380  %6 = getelementptr inbounds <4 x i32>, ptr %5, i64 181  ret ptr %682}83 84; It is valid to swap if the source operand of the first GEP has multiple uses.85define ptr @multipleUses1(ptr %p) {86; CHECK-LABEL: @multipleUses1(87; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P:%.*]], i64 488; CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[P]] to i6489; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 [[TMP2]]90; CHECK-NEXT:    ret ptr [[TMP3]]91;92  %1 = getelementptr inbounds i32, ptr %p, i64 193  %2 = ptrtoint ptr %p to i6494  %3 = getelementptr inbounds i32, ptr %1, i64 %295  ret ptr %396}97 98; It is valid to swap if the second GEP has multiple uses.99define ptr @multipleUses2(ptr %p, i64 %a) {100; CHECK-LABEL: @multipleUses2(101; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P:%.*]], i64 4102; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 [[A:%.*]]103; CHECK-NEXT:    call void @use(ptr nonnull [[TMP2]])104; CHECK-NEXT:    ret ptr [[TMP2]]105;106  %1 = getelementptr inbounds i32, ptr %p, i64 1107  %2 = getelementptr inbounds i32, ptr %1, i64 %a108  call void @use(ptr %2)109  ret ptr %2110}111 112; Negative test. It is not valid to swap if the first GEP has multiple uses.113define ptr @multipleUses3(ptr %p) {114; CHECK-LABEL: @multipleUses3(115; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P:%.*]], i64 4116; CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[TMP1]] to i64117; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 [[TMP2]]118; CHECK-NEXT:    ret ptr [[TMP3]]119;120  %1 = getelementptr inbounds i32, ptr %p, i64 1121  %2 = ptrtoint ptr %1 to i64122  %3 = getelementptr inbounds i32, ptr %1, i64 %2123  ret ptr %3124}125 126define ptr @merge_nuw(ptr %p, i64 %a) {127; CHECK-LABEL: @merge_nuw(128; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr nuw i32, ptr [[P:%.*]], i64 [[A:%.*]]129; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr nuw i8, ptr [[GEP2]], i64 5130; CHECK-NEXT:    ret ptr [[GEP3]]131;132  %gep1 = getelementptr nuw i8, ptr %p, i64 1133  %gep2 = getelementptr nuw i32, ptr %gep1, i64 %a134  %gep3 = getelementptr nuw i32, ptr %gep2, i64 1135  ret ptr %gep3136}137 138define ptr @merge_nuw_inbounds(ptr %p, i64 %a) {139; CHECK-LABEL: @merge_nuw_inbounds(140; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr inbounds nuw i32, ptr [[P:%.*]], i64 [[A:%.*]]141; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr inbounds nuw i8, ptr [[GEP2]], i64 5142; CHECK-NEXT:    ret ptr [[GEP3]]143;144  %gep1 = getelementptr inbounds nuw i8, ptr %p, i64 1145  %gep2 = getelementptr inbounds nuw i32, ptr %gep1, i64 %a146  %gep3 = getelementptr inbounds nuw i32, ptr %gep2, i64 1147  ret ptr %gep3148}149 150; It would be okay to preserve nusw here, as the constant addition does not151; overflow.152define ptr @merge_nuw_nusw(ptr %p, i64 %a) {153; CHECK-LABEL: @merge_nuw_nusw(154; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr nusw nuw i32, ptr [[P:%.*]], i64 [[A:%.*]]155; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr nuw i8, ptr [[GEP2]], i64 5156; CHECK-NEXT:    ret ptr [[GEP3]]157;158  %gep1 = getelementptr nusw nuw i8, ptr %p, i64 1159  %gep2 = getelementptr nusw nuw i32, ptr %gep1, i64 %a160  %gep3 = getelementptr nusw nuw i32, ptr %gep2, i64 1161  ret ptr %gep3162}163 164; Can't preserve nusw on the final GEP165define ptr @merge_nuw_nusw_overflow(ptr %p, i64 %a) {166; CHECK-LABEL: @merge_nuw_nusw_overflow(167; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr nusw nuw i32, ptr [[P:%.*]], i64 [[A:%.*]]168; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr nuw i8, ptr [[GEP2]], i64 -2305843009213693952169; CHECK-NEXT:    ret ptr [[GEP3]]170;171  %gep1 = getelementptr nusw nuw i8, ptr %p, i64 u0x7000000000000000172  %gep2 = getelementptr nusw nuw i32, ptr %gep1, i64 %a173  %gep3 = getelementptr nusw nuw i8, ptr %gep2, i64 u0x7000000000000000174  ret ptr %gep3175}176 177define ptr @merge_missing_nuw1(ptr %p, i64 %a) {178; CHECK-LABEL: @merge_missing_nuw1(179; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[A:%.*]]180; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 5181; CHECK-NEXT:    ret ptr [[GEP3]]182;183  %gep1 = getelementptr i8, ptr %p, i64 1184  %gep2 = getelementptr nuw i32, ptr %gep1, i64 %a185  %gep3 = getelementptr nuw i32, ptr %gep2, i64 1186  ret ptr %gep3187}188 189define ptr @merge_missing_nuw2(ptr %p, i64 %a) {190; CHECK-LABEL: @merge_missing_nuw2(191; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[A:%.*]]192; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 5193; CHECK-NEXT:    ret ptr [[GEP3]]194;195  %gep1 = getelementptr nuw i8, ptr %p, i64 1196  %gep2 = getelementptr i32, ptr %gep1, i64 %a197  %gep3 = getelementptr nuw i32, ptr %gep2, i64 1198  ret ptr %gep3199}200 201define ptr @merge_missing_nuw3(ptr %p, i64 %a) {202; CHECK-LABEL: @merge_missing_nuw3(203; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr nuw i32, ptr [[P:%.*]], i64 [[A:%.*]]204; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 5205; CHECK-NEXT:    ret ptr [[GEP3]]206;207  %gep1 = getelementptr nuw i8, ptr %p, i64 1208  %gep2 = getelementptr nuw i32, ptr %gep1, i64 %a209  %gep3 = getelementptr i32, ptr %gep2, i64 1210  ret ptr %gep3211}212 213define ptr @merge_nuw_missing_inbounds(ptr %p, i64 %a) {214; CHECK-LABEL: @merge_nuw_missing_inbounds(215; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr nuw i32, ptr [[P:%.*]], i64 [[A:%.*]]216; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr nuw i8, ptr [[GEP2]], i64 5217; CHECK-NEXT:    ret ptr [[GEP3]]218;219  %gep1 = getelementptr nuw i8, ptr %p, i64 1220  %gep2 = getelementptr inbounds nuw i32, ptr %gep1, i64 %a221  %gep3 = getelementptr inbounds nuw i32, ptr %gep2, i64 1222  ret ptr %gep3223}224 225define ptr @merge_nuw_missing_nusw(ptr %p, i64 %a) {226; CHECK-LABEL: @merge_nuw_missing_nusw(227; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr nuw i32, ptr [[P:%.*]], i64 [[A:%.*]]228; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr nuw i8, ptr [[GEP2]], i64 5229; CHECK-NEXT:    ret ptr [[GEP3]]230;231  %gep1 = getelementptr nusw nuw i8, ptr %p, i64 1232  %gep2 = getelementptr nuw i32, ptr %gep1, i64 %a233  %gep3 = getelementptr nusw nuw i32, ptr %gep2, i64 1234  ret ptr %gep3235}236 237define ptr @merge_inbounds_missing_nuw(ptr %p, i64 %a) {238; CHECK-LABEL: @merge_inbounds_missing_nuw(239; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[A:%.*]]240; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 5241; CHECK-NEXT:    ret ptr [[GEP3]]242;243  %gep1 = getelementptr inbounds nuw i8, ptr %p, i64 1244  %gep2 = getelementptr inbounds i32, ptr %gep1, i64 %a245  %gep3 = getelementptr inbounds nuw i32, ptr %gep2, i64 1246  ret ptr %gep3247}248 249define ptr @merge_nusw_missing_nuw(ptr %p, i64 %a) {250; CHECK-LABEL: @merge_nusw_missing_nuw(251; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[A:%.*]]252; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 5253; CHECK-NEXT:    ret ptr [[GEP3]]254;255  %gep1 = getelementptr nusw nuw i8, ptr %p, i64 1256  %gep2 = getelementptr nusw i32, ptr %gep1, i64 %a257  %gep3 = getelementptr nusw nuw i32, ptr %gep2, i64 1258  ret ptr %gep3259}260