brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.6 KiB · 5d162e5 Raw
608 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine,verify -S < %s | FileCheck %s --check-prefixes=ALL,INSTCOMBINE3 4; Make sure GVN won't undo the transformation:5; RUN: opt -passes=instcombine,gvn -S < %s | FileCheck %s --check-prefixes=ALL,INSTCOMBINEGVN6 7declare ptr @get_ptr.i8()8declare ptr @get_ptr.i32()9declare void @foo.i8(ptr)10declare void @foo.i32(ptr)11 12define i32 @test_gep_and_bitcast(i1 %cond, i1 %cond2) {13; ALL-LABEL: @test_gep_and_bitcast(14; ALL-NEXT:  entry:15; ALL-NEXT:    [[OBJ:%.*]] = call ptr @get_ptr.i8()16; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]17; ALL:       bb1:18; ALL-NEXT:    br label [[EXIT:%.*]]19; ALL:       bb2:20; ALL-NEXT:    br label [[EXIT]]21; ALL:       exit:22; ALL-NEXT:    [[PTR_TYPED:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ]], i64 1623; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, ptr [[PTR_TYPED]], align 424; ALL-NEXT:    store i32 1, ptr [[PTR_TYPED]], align 425; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 126; ALL-NEXT:    ret i32 [[RES]]27;28entry:29  %obj = call ptr @get_ptr.i8()30  br i1 %cond, label %bb1, label %bb231 32bb1:33  %ptr1 = getelementptr inbounds i8, ptr %obj, i64 1634  %res1 = load i32, ptr %ptr135  br label %exit36 37bb2:38  %ptr2 = getelementptr inbounds i8, ptr %obj, i64 1639  %res2 = load i32, ptr %ptr240  br label %exit41 42exit:43  %ptr.typed = phi ptr [ %ptr1, %bb1 ], [ %ptr2, %bb2 ]44  %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]45  store i32 1, ptr %ptr.typed46  %res.load = load i32, ptr %ptr.typed47  %res = select i1 %cond2, i32 %res.phi, i32 %res.load48  ret i32 %res49}50 51define i32 @test_gep_and_bitcast_arg(ptr %obj, i1 %cond, i1 %cond2) {52; ALL-LABEL: @test_gep_and_bitcast_arg(53; ALL-NEXT:  entry:54; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]55; ALL:       bb1:56; ALL-NEXT:    br label [[EXIT:%.*]]57; ALL:       bb2:58; ALL-NEXT:    br label [[EXIT]]59; ALL:       exit:60; ALL-NEXT:    [[PTR_TYPED:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ:%.*]], i64 1661; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, ptr [[PTR_TYPED]], align 462; ALL-NEXT:    store i32 1, ptr [[PTR_TYPED]], align 463; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 164; ALL-NEXT:    ret i32 [[RES]]65;66entry:67  br i1 %cond, label %bb1, label %bb268 69bb1:70  %ptr1 = getelementptr inbounds i8, ptr %obj, i64 1671  %res1 = load i32, ptr %ptr172  br label %exit73 74bb2:75  %ptr2 = getelementptr inbounds i8, ptr %obj, i64 1676  %res2 = load i32, ptr %ptr277  br label %exit78 79exit:80  %ptr.typed = phi ptr [ %ptr1, %bb1 ], [ %ptr2, %bb2 ]81  %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]82  store i32 1, ptr %ptr.typed83  %res.load = load i32, ptr %ptr.typed84  %res = select i1 %cond2, i32 %res.phi, i32 %res.load85  ret i32 %res86}87 88define i32 @test_gep_and_bitcast_phi(i1 %cond, i1 %cond2, i1 %cond3) {89; ALL-LABEL: @test_gep_and_bitcast_phi(90; ALL-NEXT:  entry:91; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]92; ALL:       bb1:93; ALL-NEXT:    [[OBJ1:%.*]] = call ptr @get_ptr.i8()94; ALL-NEXT:    br label [[MERGE:%.*]]95; ALL:       bb2:96; ALL-NEXT:    [[OBJ2_TYPED:%.*]] = call ptr @get_ptr.i32()97; ALL-NEXT:    br label [[MERGE]]98; ALL:       merge:99; ALL-NEXT:    [[OBJ:%.*]] = phi ptr [ [[OBJ1]], [[BB1]] ], [ [[OBJ2_TYPED]], [[BB2]] ]100; ALL-NEXT:    [[ANOTHER_PHI:%.*]] = phi ptr [ [[OBJ1]], [[BB1]] ], [ null, [[BB2]] ]101; ALL-NEXT:    call void @foo.i8(ptr [[ANOTHER_PHI]])102; ALL-NEXT:    br i1 [[COND2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]103; ALL:       bb3:104; ALL-NEXT:    br label [[EXIT:%.*]]105; ALL:       bb4:106; ALL-NEXT:    br label [[EXIT]]107; ALL:       exit:108; ALL-NEXT:    [[PTR_TYPED:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ]], i64 16109; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, ptr [[PTR_TYPED]], align 4110; ALL-NEXT:    store i32 1, ptr [[PTR_TYPED]], align 4111; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND3:%.*]], i32 [[RES_PHI]], i32 1112; ALL-NEXT:    ret i32 [[RES]]113;114entry:115  br i1 %cond, label %bb1, label %bb2116 117bb1:118  %obj1 = call ptr @get_ptr.i8()119  br label %merge120 121bb2:122  %obj2.typed = call ptr @get_ptr.i32()123  br label %merge124 125merge:126  %obj = phi ptr [ %obj1, %bb1 ], [ %obj2.typed, %bb2 ]127  %another_phi = phi ptr [ %obj1, %bb1 ], [ null, %bb2 ]128  call void @foo.i8(ptr %another_phi)129  br i1 %cond2, label %bb3, label %bb4130 131bb3:132  %ptr1 = getelementptr inbounds i8, ptr %obj, i64 16133  %res1 = load i32, ptr %ptr1134  br label %exit135 136bb4:137  %ptr2 = getelementptr inbounds i8, ptr %obj, i64 16138  %res2 = load i32, ptr %ptr2139  br label %exit140 141exit:142  %ptr.typed = phi ptr [ %ptr1, %bb3 ], [ %ptr2, %bb4 ]143  %res.phi = phi i32 [ %res1, %bb3 ], [ %res2, %bb4 ]144  store i32 1, ptr %ptr.typed145  %res.load = load i32, ptr %ptr.typed146  %res = select i1 %cond3, i32 %res.phi, i32 %res.load147  ret i32 %res148}149 150define i32 @test_gep_i32ptr(i1 %cond, i1 %cond2) {151; ALL-LABEL: @test_gep_i32ptr(152; ALL-NEXT:  entry:153; ALL-NEXT:    [[OBJ:%.*]] = call ptr @get_ptr.i32()154; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]155; ALL:       bb1:156; ALL-NEXT:    br label [[EXIT:%.*]]157; ALL:       bb2:158; ALL-NEXT:    br label [[EXIT]]159; ALL:       exit:160; ALL-NEXT:    [[PTR_TYPED:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ]], i64 64161; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, ptr [[PTR_TYPED]], align 4162; ALL-NEXT:    store i32 1, ptr [[PTR_TYPED]], align 4163; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1164; ALL-NEXT:    ret i32 [[RES]]165;166entry:167  %obj = call ptr @get_ptr.i32()168  br i1 %cond, label %bb1, label %bb2169 170bb1:171  %ptr1.typed = getelementptr inbounds i32, ptr %obj, i64 16172  %res1 = load i32, ptr %ptr1.typed173  br label %exit174 175bb2:176  %ptr2.typed = getelementptr inbounds i32, ptr %obj, i64 16177  %res2 = load i32, ptr %ptr2.typed178  br label %exit179 180exit:181  %ptr.typed = phi ptr [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ]182  %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]183  store i32 1, ptr %ptr.typed184  %res.load = load i32, ptr %ptr.typed185  %res = select i1 %cond2, i32 %res.phi, i32 %res.load186  ret i32 %res187}188 189define i32 @test_gep_and_bitcast_gep_base_ptr(i1 %cond, i1 %cond2) {190; ALL-LABEL: @test_gep_and_bitcast_gep_base_ptr(191; ALL-NEXT:  entry:192; ALL-NEXT:    [[OBJ0:%.*]] = call ptr @get_ptr.i8()193; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]194; ALL:       bb1:195; ALL-NEXT:    br label [[EXIT:%.*]]196; ALL:       bb2:197; ALL-NEXT:    br label [[EXIT]]198; ALL:       exit:199; ALL-NEXT:    [[PTR_TYPED:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ0]], i64 32200; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, ptr [[PTR_TYPED]], align 4201; ALL-NEXT:    store i32 1, ptr [[PTR_TYPED]], align 4202; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1203; ALL-NEXT:    ret i32 [[RES]]204;205entry:206  %obj0 = call ptr @get_ptr.i8()207  %obj = getelementptr inbounds i8, ptr %obj0, i64 16208  br i1 %cond, label %bb1, label %bb2209 210bb1:211  %ptr1 = getelementptr inbounds i8, ptr %obj, i64 16212  %res1 = load i32, ptr %ptr1213  br label %exit214 215bb2:216  %ptr2 = getelementptr inbounds i8, ptr %obj, i64 16217  %res2 = load i32, ptr %ptr2218  br label %exit219 220exit:221  %ptr.typed = phi ptr [ %ptr1, %bb1 ], [ %ptr2, %bb2 ]222  %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]223  store i32 1, ptr %ptr.typed224  %res.load = load i32, ptr %ptr.typed225  %res = select i1 %cond2, i32 %res.phi, i32 %res.load226  ret i32 %res227}228 229define i32 @test_gep_and_bitcast_same_bb(i1 %cond, i1 %cond2) {230; ALL-LABEL: @test_gep_and_bitcast_same_bb(231; ALL-NEXT:  entry:232; ALL-NEXT:    [[OBJ:%.*]] = call ptr @get_ptr.i8()233; ALL-NEXT:    br i1 [[COND:%.*]], label [[EXIT:%.*]], label [[BB2:%.*]]234; ALL:       bb2:235; ALL-NEXT:    br label [[EXIT]]236; ALL:       exit:237; ALL-NEXT:    [[PTR_TYPED:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ]], i64 16238; ALL-NEXT:    [[RES_PHI:%.*]] = load i32, ptr [[PTR_TYPED]], align 4239; ALL-NEXT:    store i32 1, ptr [[PTR_TYPED]], align 4240; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1241; ALL-NEXT:    ret i32 [[RES]]242;243entry:244  %obj = call ptr @get_ptr.i8()245  %ptr1 = getelementptr inbounds i8, ptr %obj, i64 16246  %res1 = load i32, ptr %ptr1247  br i1 %cond, label %exit, label %bb2248 249bb2:250  %ptr2 = getelementptr inbounds i8, ptr %obj, i64 16251  %res2 = load i32, ptr %ptr2252  br label %exit253 254exit:255  %ptr.typed = phi ptr [ %ptr1, %entry ], [ %ptr2, %bb2 ]256  %res.phi = phi i32 [ %res1, %entry ], [ %res2, %bb2 ]257  store i32 1, ptr %ptr.typed258  %res.load = load i32, ptr %ptr.typed259  %res = select i1 %cond2, i32 %res.phi, i32 %res.load260  ret i32 %res261}262 263define i32 @test_gep_and_bitcast_same_bb_and_extra_use(i1 %cond, i1 %cond2) {264; INSTCOMBINE-LABEL: @test_gep_and_bitcast_same_bb_and_extra_use(265; INSTCOMBINE-NEXT:  entry:266; INSTCOMBINE-NEXT:    [[OBJ:%.*]] = call ptr @get_ptr.i8()267; INSTCOMBINE-NEXT:    [[PTR1:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ]], i64 16268; INSTCOMBINE-NEXT:    call void @foo.i32(ptr nonnull [[PTR1]])269; INSTCOMBINE-NEXT:    br i1 [[COND:%.*]], label [[EXIT:%.*]], label [[BB2:%.*]]270; INSTCOMBINE:       bb2:271; INSTCOMBINE-NEXT:    [[PTR2:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ]], i64 16272; INSTCOMBINE-NEXT:    br label [[EXIT]]273; INSTCOMBINE:       exit:274; INSTCOMBINE-NEXT:    [[PTR_TYPED:%.*]] = phi ptr [ [[PTR1]], [[ENTRY:%.*]] ], [ [[PTR2]], [[BB2]] ]275; INSTCOMBINE-NEXT:    [[RES_PHI:%.*]] = load i32, ptr [[PTR_TYPED]], align 4276; INSTCOMBINE-NEXT:    store i32 1, ptr [[PTR_TYPED]], align 4277; INSTCOMBINE-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1278; INSTCOMBINE-NEXT:    ret i32 [[RES]]279;280; INSTCOMBINEGVN-LABEL: @test_gep_and_bitcast_same_bb_and_extra_use(281; INSTCOMBINEGVN-NEXT:  entry:282; INSTCOMBINEGVN-NEXT:    [[OBJ:%.*]] = call ptr @get_ptr.i8()283; INSTCOMBINEGVN-NEXT:    [[PTR1:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ]], i64 16284; INSTCOMBINEGVN-NEXT:    call void @foo.i32(ptr nonnull [[PTR1]])285; INSTCOMBINEGVN-NEXT:    br i1 [[COND:%.*]], label [[EXIT:%.*]], label [[BB2:%.*]]286; INSTCOMBINEGVN:       bb2:287; INSTCOMBINEGVN-NEXT:    br label [[EXIT]]288; INSTCOMBINEGVN:       exit:289; INSTCOMBINEGVN-NEXT:    [[RES_PHI:%.*]] = load i32, ptr [[PTR1]], align 4290; INSTCOMBINEGVN-NEXT:    store i32 1, ptr [[PTR1]], align 4291; INSTCOMBINEGVN-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1292; INSTCOMBINEGVN-NEXT:    ret i32 [[RES]]293;294entry:295  %obj = call ptr @get_ptr.i8()296  %ptr1 = getelementptr inbounds i8, ptr %obj, i64 16297  call void @foo.i32(ptr %ptr1)298  %res1 = load i32, ptr %ptr1299  br i1 %cond, label %exit, label %bb2300 301bb2:302  %ptr2 = getelementptr inbounds i8, ptr %obj, i64 16303  %res2 = load i32, ptr %ptr2304  br label %exit305 306exit:307  %ptr.typed = phi ptr [ %ptr1, %entry ], [ %ptr2, %bb2 ]308  %res.phi = phi i32 [ %res1, %entry ], [ %res2, %bb2 ]309  store i32 1, ptr %ptr.typed310  %res.load = load i32, ptr %ptr.typed311  %res = select i1 %cond2, i32 %res.phi, i32 %res.load312  ret i32 %res313}314 315define i8 @test_gep(i1 %cond, i1 %cond2) {316; ALL-LABEL: @test_gep(317; ALL-NEXT:  entry:318; ALL-NEXT:    [[OBJ:%.*]] = call ptr @get_ptr.i8()319; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]320; ALL:       bb1:321; ALL-NEXT:    br label [[EXIT:%.*]]322; ALL:       bb2:323; ALL-NEXT:    br label [[EXIT]]324; ALL:       exit:325; ALL-NEXT:    [[PTR_TYPED:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ]], i64 16326; ALL-NEXT:    [[RES_PHI:%.*]] = load i8, ptr [[PTR_TYPED]], align 1327; ALL-NEXT:    store i8 1, ptr [[PTR_TYPED]], align 1328; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i8 [[RES_PHI]], i8 1329; ALL-NEXT:    ret i8 [[RES]]330;331entry:332  %obj = call ptr @get_ptr.i8()333  br i1 %cond, label %bb1, label %bb2334 335bb1:336  %ptr1 = getelementptr inbounds i8, ptr %obj, i64 16337  %res1 = load i8, ptr %ptr1338  br label %exit339 340bb2:341  %ptr2 = getelementptr inbounds i8, ptr %obj, i64 16342  %res2 = load i8, ptr %ptr2343  br label %exit344 345exit:346  %ptr.typed = phi ptr [ %ptr1, %bb1 ], [ %ptr2, %bb2 ]347  %res.phi = phi i8 [ %res1, %bb1 ], [ %res2, %bb2 ]348  store i8 1, ptr %ptr.typed349  %res.load = load i8, ptr %ptr.typed350  %res = select i1 %cond2, i8 %res.phi, i8 %res.load351  ret i8 %res352}353 354define i32 @test_extra_uses(i1 %cond, i1 %cond2) {355; ALL-LABEL: @test_extra_uses(356; ALL-NEXT:  entry:357; ALL-NEXT:    [[OBJ:%.*]] = call ptr @get_ptr.i8()358; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]359; ALL:       bb1:360; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ]], i64 16361; ALL-NEXT:    [[RES1:%.*]] = load i32, ptr [[PTR1]], align 4362; ALL-NEXT:    call void @foo.i32(ptr nonnull [[PTR1]])363; ALL-NEXT:    br label [[EXIT:%.*]]364; ALL:       bb2:365; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ]], i64 16366; ALL-NEXT:    [[RES2:%.*]] = load i32, ptr [[PTR2]], align 4367; ALL-NEXT:    call void @foo.i32(ptr nonnull [[PTR2]])368; ALL-NEXT:    br label [[EXIT]]369; ALL:       exit:370; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi ptr [ [[PTR1]], [[BB1]] ], [ [[PTR2]], [[BB2]] ]371; ALL-NEXT:    [[RES_PHI:%.*]] = phi i32 [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ]372; ALL-NEXT:    store i32 1, ptr [[PTR_TYPED]], align 4373; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1374; ALL-NEXT:    ret i32 [[RES]]375;376entry:377  %obj = call ptr @get_ptr.i8()378  br i1 %cond, label %bb1, label %bb2379 380bb1:381  %ptr1 = getelementptr inbounds i8, ptr %obj, i64 16382  %res1 = load i32, ptr %ptr1383  call void @foo.i32(ptr %ptr1)384  br label %exit385 386bb2:387  %ptr2 = getelementptr inbounds i8, ptr %obj, i64 16388  %res2 = load i32, ptr %ptr2389  call void @foo.i32(ptr %ptr2)390  br label %exit391 392exit:393  %ptr.typed = phi ptr [ %ptr1, %bb1 ], [ %ptr2, %bb2 ]394  %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]395  store i32 1, ptr %ptr.typed396  %res.load = load i32, ptr %ptr.typed397  %res = select i1 %cond2, i32 %res.phi, i32 %res.load398  ret i32 %res399}400 401define i32 @test_extra_uses_non_inbounds(i1 %cond, i1 %cond2) {402; ALL-LABEL: @test_extra_uses_non_inbounds(403; ALL-NEXT:  entry:404; ALL-NEXT:    [[OBJ:%.*]] = call ptr @get_ptr.i8()405; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]406; ALL:       bb1:407; ALL-NEXT:    [[PTR1:%.*]] = getelementptr i8, ptr [[OBJ]], i64 16408; ALL-NEXT:    [[RES1:%.*]] = load i32, ptr [[PTR1]], align 4409; ALL-NEXT:    call void @foo.i32(ptr nonnull [[PTR1]])410; ALL-NEXT:    br label [[EXIT:%.*]]411; ALL:       bb2:412; ALL-NEXT:    [[PTR2:%.*]] = getelementptr i8, ptr [[OBJ]], i64 16413; ALL-NEXT:    [[RES2:%.*]] = load i32, ptr [[PTR2]], align 4414; ALL-NEXT:    call void @foo.i32(ptr nonnull [[PTR2]])415; ALL-NEXT:    br label [[EXIT]]416; ALL:       exit:417; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi ptr [ [[PTR1]], [[BB1]] ], [ [[PTR2]], [[BB2]] ]418; ALL-NEXT:    [[RES_PHI:%.*]] = phi i32 [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ]419; ALL-NEXT:    store i32 1, ptr [[PTR_TYPED]], align 4420; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1421; ALL-NEXT:    ret i32 [[RES]]422;423entry:424  %obj = call ptr @get_ptr.i8()425  br i1 %cond, label %bb1, label %bb2426 427bb1:428  %ptr1 = getelementptr i8, ptr %obj, i64 16429  %res1 = load i32, ptr %ptr1430  call void @foo.i32(ptr %ptr1)431  br label %exit432 433bb2:434  %ptr2 = getelementptr i8, ptr %obj, i64 16435  %res2 = load i32, ptr %ptr2436  call void @foo.i32(ptr %ptr2)437  br label %exit438 439exit:440  %ptr.typed = phi ptr [ %ptr1, %bb1 ], [ %ptr2, %bb2 ]441  %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]442  store i32 1, ptr %ptr.typed443  %res.load = load i32, ptr %ptr.typed444  %res = select i1 %cond2, i32 %res.phi, i32 %res.load445  ret i32 %res446}447 448define i32 @test_extra_uses_multiple_geps(i1 %cond, i1 %cond2) {449; ALL-LABEL: @test_extra_uses_multiple_geps(450; ALL-NEXT:  entry:451; ALL-NEXT:    [[OBJ:%.*]] = call ptr @get_ptr.i8()452; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]453; ALL:       bb1:454; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ]], i64 16455; ALL-NEXT:    [[RES1:%.*]] = load i32, ptr [[PTR1]], align 4456; ALL-NEXT:    call void @foo.i32(ptr nonnull [[PTR1]])457; ALL-NEXT:    br label [[EXIT:%.*]]458; ALL:       bb2:459; ALL-NEXT:    [[PTR2_1:%.*]] = getelementptr i8, ptr [[OBJ]], i64 16460; ALL-NEXT:    [[RES2:%.*]] = load i32, ptr [[PTR2_1]], align 4461; ALL-NEXT:    call void @foo.i32(ptr nonnull [[PTR2_1]])462; ALL-NEXT:    br label [[EXIT]]463; ALL:       exit:464; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi ptr [ [[PTR1]], [[BB1]] ], [ [[PTR2_1]], [[BB2]] ]465; ALL-NEXT:    [[RES_PHI:%.*]] = phi i32 [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ]466; ALL-NEXT:    store i32 1, ptr [[PTR_TYPED]], align 4467; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1468; ALL-NEXT:    ret i32 [[RES]]469;470entry:471  %obj = call ptr @get_ptr.i8()472  br i1 %cond, label %bb1, label %bb2473 474bb1:475  %ptr1 = getelementptr inbounds i8, ptr %obj, i64 16476  %res1 = load i32, ptr %ptr1477  call void @foo.i32(ptr %ptr1)478  br label %exit479 480bb2:481  %ptr2.0 = getelementptr i8, ptr %obj, i64 8482  %ptr2.1 = getelementptr inbounds i8, ptr %ptr2.0, i64 8483  %res2 = load i32, ptr %ptr2.1484  call void @foo.i32(ptr %ptr2.1)485  br label %exit486 487exit:488  %ptr.typed = phi ptr [ %ptr1, %bb1 ], [ %ptr2.1, %bb2 ]489  %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]490  store i32 1, ptr %ptr.typed491  %res.load = load i32, ptr %ptr.typed492  %res = select i1 %cond2, i32 %res.phi, i32 %res.load493  ret i32 %res494}495 496define i8 @test_gep_extra_uses(i1 %cond, i1 %cond2) {497; ALL-LABEL: @test_gep_extra_uses(498; ALL-NEXT:  entry:499; ALL-NEXT:    [[OBJ:%.*]] = call ptr @get_ptr.i8()500; ALL-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]501; ALL:       bb1:502; ALL-NEXT:    [[PTR1:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ]], i64 16503; ALL-NEXT:    [[RES1:%.*]] = load i8, ptr [[PTR1]], align 1504; ALL-NEXT:    call void @foo.i8(ptr nonnull [[PTR1]])505; ALL-NEXT:    br label [[EXIT:%.*]]506; ALL:       bb2:507; ALL-NEXT:    [[PTR2:%.*]] = getelementptr inbounds nuw i8, ptr [[OBJ]], i64 16508; ALL-NEXT:    [[RES2:%.*]] = load i8, ptr [[PTR2]], align 1509; ALL-NEXT:    call void @foo.i8(ptr nonnull [[PTR2]])510; ALL-NEXT:    br label [[EXIT]]511; ALL:       exit:512; ALL-NEXT:    [[PTR_TYPED:%.*]] = phi ptr [ [[PTR1]], [[BB1]] ], [ [[PTR2]], [[BB2]] ]513; ALL-NEXT:    [[RES_PHI:%.*]] = phi i8 [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ]514; ALL-NEXT:    store i8 1, ptr [[PTR_TYPED]], align 1515; ALL-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], i8 [[RES_PHI]], i8 1516; ALL-NEXT:    ret i8 [[RES]]517;518entry:519  %obj = call ptr @get_ptr.i8()520  br i1 %cond, label %bb1, label %bb2521 522bb1:523  %ptr1 = getelementptr inbounds i8, ptr %obj, i64 16524  %res1 = load i8, ptr %ptr1525  call void @foo.i8(ptr %ptr1)526  br label %exit527 528bb2:529  %ptr2 = getelementptr inbounds i8, ptr %obj, i64 16530  %res2 = load i8, ptr %ptr2531  call void @foo.i8(ptr %ptr2)532  br label %exit533 534exit:535  %ptr.typed = phi ptr [ %ptr1, %bb1 ], [ %ptr2, %bb2 ]536  %res.phi = phi i8 [ %res1, %bb1 ], [ %res2, %bb2 ]537  store i8 1, ptr %ptr.typed538  %res.load = load i8, ptr %ptr.typed539  %res = select i1 %cond2, i8 %res.phi, i8 %res.load540  ret i8 %res541}542 543; `swifterror` addresses are restricted to load and stores and call arguments.544declare void @takeAddress(ptr swifterror)545 546define ptr @test_dont_optimize_swifterror(i1 %cond, i1 %cond2, ptr %ptr) {547; INSTCOMBINE-LABEL: @test_dont_optimize_swifterror(548; INSTCOMBINE-NEXT:  entry:549; INSTCOMBINE-NEXT:    [[OBJ:%.*]] = alloca swifterror ptr, align 8550; INSTCOMBINE-NEXT:    [[OBJ2:%.*]] = alloca swifterror ptr, align 8551; INSTCOMBINE-NEXT:    call void @takeAddress(ptr nonnull swifterror [[OBJ]])552; INSTCOMBINE-NEXT:    call void @takeAddress(ptr nonnull swifterror [[OBJ2]])553; INSTCOMBINE-NEXT:    store ptr [[PTR:%.*]], ptr [[OBJ]], align 8554; INSTCOMBINE-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]555; INSTCOMBINE:       bb1:556; INSTCOMBINE-NEXT:    [[RES1:%.*]] = load ptr, ptr [[OBJ]], align 8557; INSTCOMBINE-NEXT:    br label [[EXIT:%.*]]558; INSTCOMBINE:       bb2:559; INSTCOMBINE-NEXT:    [[RES2:%.*]] = load ptr, ptr [[OBJ2]], align 8560; INSTCOMBINE-NEXT:    br label [[EXIT]]561; INSTCOMBINE:       exit:562; INSTCOMBINE-NEXT:    [[RES_PHI:%.*]] = phi ptr [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ]563; INSTCOMBINE-NEXT:    store ptr null, ptr [[OBJ]], align 8564; INSTCOMBINE-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], ptr [[RES_PHI]], ptr null565; INSTCOMBINE-NEXT:    ret ptr [[RES]]566;567; INSTCOMBINEGVN-LABEL: @test_dont_optimize_swifterror(568; INSTCOMBINEGVN-NEXT:  entry:569; INSTCOMBINEGVN-NEXT:    [[OBJ:%.*]] = alloca swifterror ptr, align 8570; INSTCOMBINEGVN-NEXT:    [[OBJ2:%.*]] = alloca swifterror ptr, align 8571; INSTCOMBINEGVN-NEXT:    call void @takeAddress(ptr nonnull swifterror [[OBJ]])572; INSTCOMBINEGVN-NEXT:    call void @takeAddress(ptr nonnull swifterror [[OBJ2]])573; INSTCOMBINEGVN-NEXT:    store ptr [[PTR:%.*]], ptr [[OBJ]], align 8574; INSTCOMBINEGVN-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]575; INSTCOMBINEGVN:       bb1:576; INSTCOMBINEGVN-NEXT:    br label [[EXIT:%.*]]577; INSTCOMBINEGVN:       bb2:578; INSTCOMBINEGVN-NEXT:    [[RES2:%.*]] = load ptr, ptr [[OBJ2]], align 8579; INSTCOMBINEGVN-NEXT:    br label [[EXIT]]580; INSTCOMBINEGVN:       exit:581; INSTCOMBINEGVN-NEXT:    [[RES_PHI:%.*]] = phi ptr [ [[PTR]], [[BB1]] ], [ [[RES2]], [[BB2]] ]582; INSTCOMBINEGVN-NEXT:    store ptr null, ptr [[OBJ]], align 8583; INSTCOMBINEGVN-NEXT:    [[RES:%.*]] = select i1 [[COND2:%.*]], ptr [[RES_PHI]], ptr null584; INSTCOMBINEGVN-NEXT:    ret ptr [[RES]]585;586entry:587  %obj = alloca swifterror ptr, align 8588  %obj2 = alloca swifterror ptr, align 8589  call void @takeAddress(ptr swifterror %obj)590  call void @takeAddress(ptr swifterror %obj2)591  store ptr %ptr, ptr %obj, align 8592  br i1 %cond, label %bb1, label %bb2593 594bb1:                                              ; preds = %entry595  %res1 = load ptr, ptr %obj, align 8596  br label %exit597 598bb2:                                              ; preds = %entry599  %res2 = load ptr, ptr %obj2, align 8600  br label %exit601 602exit:                                             ; preds = %bb2, %bb1603  %res.phi = phi ptr [ %res1, %bb1 ], [ %res2, %bb2 ]604  store ptr null, ptr %obj, align 8605  %res = select i1 %cond2, ptr %res.phi, ptr null606  ret ptr %res607}608