1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -simplifycfg < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; SimplifyCFG should eliminate redundant indirectbr edges. 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Worker; CHECK: indbrtest0 6*9880d681SAndroid Build Coastguard Worker; CHECK: indirectbr i8* %t, [label %BB0, label %BB1, label %BB2] 7*9880d681SAndroid Build Coastguard Worker; CHECK: %x = phi i32 [ 0, %BB0 ], [ 1, %entry ] 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Workerdeclare void @foo() 10*9880d681SAndroid Build Coastguard Workerdeclare void @A() 11*9880d681SAndroid Build Coastguard Workerdeclare void @B(i32) 12*9880d681SAndroid Build Coastguard Workerdeclare void @C() 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest0(i8** %P, i8** %Q) { 15*9880d681SAndroid Build Coastguard Workerentry: 16*9880d681SAndroid Build Coastguard Worker store i8* blockaddress(@indbrtest0, %BB0), i8** %P 17*9880d681SAndroid Build Coastguard Worker store i8* blockaddress(@indbrtest0, %BB1), i8** %P 18*9880d681SAndroid Build Coastguard Worker store i8* blockaddress(@indbrtest0, %BB2), i8** %P 19*9880d681SAndroid Build Coastguard Worker call void @foo() 20*9880d681SAndroid Build Coastguard Worker %t = load i8*, i8** %Q 21*9880d681SAndroid Build Coastguard Worker indirectbr i8* %t, [label %BB0, label %BB1, label %BB2, label %BB0, label %BB1, label %BB2] 22*9880d681SAndroid Build Coastguard WorkerBB0: 23*9880d681SAndroid Build Coastguard Worker call void @A() 24*9880d681SAndroid Build Coastguard Worker br label %BB1 25*9880d681SAndroid Build Coastguard WorkerBB1: 26*9880d681SAndroid Build Coastguard Worker %x = phi i32 [ 0, %BB0 ], [ 1, %entry ], [ 1, %entry ] 27*9880d681SAndroid Build Coastguard Worker call void @B(i32 %x) 28*9880d681SAndroid Build Coastguard Worker ret void 29*9880d681SAndroid Build Coastguard WorkerBB2: 30*9880d681SAndroid Build Coastguard Worker call void @C() 31*9880d681SAndroid Build Coastguard Worker ret void 32*9880d681SAndroid Build Coastguard Worker} 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Worker; SimplifyCFG should convert the indirectbr into a directbr. It would be even 35*9880d681SAndroid Build Coastguard Worker; better if it removed the branch altogether, but simplifycfdg currently misses 36*9880d681SAndroid Build Coastguard Worker; that because the predecessor is the entry block. 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker; CHECK: indbrtest1 39*9880d681SAndroid Build Coastguard Worker; CHECK: br label %BB0 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest1(i8** %P, i8** %Q) { 42*9880d681SAndroid Build Coastguard Workerentry: 43*9880d681SAndroid Build Coastguard Worker store i8* blockaddress(@indbrtest1, %BB0), i8** %P 44*9880d681SAndroid Build Coastguard Worker call void @foo() 45*9880d681SAndroid Build Coastguard Worker %t = load i8*, i8** %Q 46*9880d681SAndroid Build Coastguard Worker indirectbr i8* %t, [label %BB0, label %BB0] 47*9880d681SAndroid Build Coastguard WorkerBB0: 48*9880d681SAndroid Build Coastguard Worker call void @A() 49*9880d681SAndroid Build Coastguard Worker ret void 50*9880d681SAndroid Build Coastguard Worker} 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker; SimplifyCFG should notice that BB0 does not have its address taken and 53*9880d681SAndroid Build Coastguard Worker; remove it from entry's successor list. 54*9880d681SAndroid Build Coastguard Worker 55*9880d681SAndroid Build Coastguard Worker; CHECK: indbrtest2 56*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 57*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: unreachable 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest2(i8* %t) { 60*9880d681SAndroid Build Coastguard Workerentry: 61*9880d681SAndroid Build Coastguard Worker indirectbr i8* %t, [label %BB0, label %BB0] 62*9880d681SAndroid Build Coastguard WorkerBB0: 63*9880d681SAndroid Build Coastguard Worker ret void 64*9880d681SAndroid Build Coastguard Worker} 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker; Make sure the blocks in the next few tests aren't trivially removable as 68*9880d681SAndroid Build Coastguard Worker; successors by taking their addresses. 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Worker@anchor = constant [13 x i8*] [ 71*9880d681SAndroid Build Coastguard Worker i8* blockaddress(@indbrtest3, %L1), i8* blockaddress(@indbrtest3, %L2), i8* blockaddress(@indbrtest3, %L3), 72*9880d681SAndroid Build Coastguard Worker i8* blockaddress(@indbrtest4, %L1), i8* blockaddress(@indbrtest4, %L2), i8* blockaddress(@indbrtest4, %L3), 73*9880d681SAndroid Build Coastguard Worker i8* blockaddress(@indbrtest5, %L1), i8* blockaddress(@indbrtest5, %L2), i8* blockaddress(@indbrtest5, %L3), i8* blockaddress(@indbrtest5, %L4), 74*9880d681SAndroid Build Coastguard Worker i8* blockaddress(@indbrtest6, %L1), i8* blockaddress(@indbrtest6, %L2), i8* blockaddress(@indbrtest6, %L3) 75*9880d681SAndroid Build Coastguard Worker] 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker; SimplifyCFG should turn the indirectbr into a conditional branch on the 78*9880d681SAndroid Build Coastguard Worker; condition of the select. 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @indbrtest3( 81*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 82*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br i1 %cond, label %L1, label %L2 83*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: indirectbr 84*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: br 85*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: L3: 86*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest3(i1 %cond, i8* %address) nounwind { 87*9880d681SAndroid Build Coastguard Workerentry: 88*9880d681SAndroid Build Coastguard Worker %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest3, %L1), i8* blockaddress(@indbrtest3, %L2) 89*9880d681SAndroid Build Coastguard Worker indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3] 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard WorkerL1: 92*9880d681SAndroid Build Coastguard Worker call void @A() 93*9880d681SAndroid Build Coastguard Worker ret void 94*9880d681SAndroid Build Coastguard WorkerL2: 95*9880d681SAndroid Build Coastguard Worker call void @C() 96*9880d681SAndroid Build Coastguard Worker ret void 97*9880d681SAndroid Build Coastguard WorkerL3: 98*9880d681SAndroid Build Coastguard Worker call void @foo() 99*9880d681SAndroid Build Coastguard Worker ret void 100*9880d681SAndroid Build Coastguard Worker} 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Worker; SimplifyCFG should turn the indirectbr into an unconditional branch to the 103*9880d681SAndroid Build Coastguard Worker; only possible destination. 104*9880d681SAndroid Build Coastguard Worker; As in @indbrtest1, it should really remove the branch entirely, but it doesn't 105*9880d681SAndroid Build Coastguard Worker; because it's in the entry block. 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @indbrtest4( 108*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 109*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %L1 110*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest4(i1 %cond) nounwind { 111*9880d681SAndroid Build Coastguard Workerentry: 112*9880d681SAndroid Build Coastguard Worker %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest4, %L1), i8* blockaddress(@indbrtest4, %L1) 113*9880d681SAndroid Build Coastguard Worker indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3] 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard WorkerL1: 116*9880d681SAndroid Build Coastguard Worker call void @A() 117*9880d681SAndroid Build Coastguard Worker ret void 118*9880d681SAndroid Build Coastguard WorkerL2: 119*9880d681SAndroid Build Coastguard Worker call void @C() 120*9880d681SAndroid Build Coastguard Worker ret void 121*9880d681SAndroid Build Coastguard WorkerL3: 122*9880d681SAndroid Build Coastguard Worker call void @foo() 123*9880d681SAndroid Build Coastguard Worker ret void 124*9880d681SAndroid Build Coastguard Worker} 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker; SimplifyCFG should turn the indirectbr into an unreachable because neither 127*9880d681SAndroid Build Coastguard Worker; destination is listed as a successor. 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @indbrtest5( 130*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 131*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: unreachable 132*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 133*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest5(i1 %cond, i8* %anchor) nounwind { 134*9880d681SAndroid Build Coastguard Workerentry: 135*9880d681SAndroid Build Coastguard Worker %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest5, %L1), i8* blockaddress(@indbrtest5, %L2) 136*9880d681SAndroid Build Coastguard Worker; This needs to have more than one successor for this test, otherwise it gets 137*9880d681SAndroid Build Coastguard Worker; replaced with an unconditional branch to the single successor. 138*9880d681SAndroid Build Coastguard Worker indirectbr i8* %indirect.goto.dest, [label %L3, label %L4] 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard WorkerL1: 141*9880d681SAndroid Build Coastguard Worker call void @A() 142*9880d681SAndroid Build Coastguard Worker ret void 143*9880d681SAndroid Build Coastguard WorkerL2: 144*9880d681SAndroid Build Coastguard Worker call void @C() 145*9880d681SAndroid Build Coastguard Worker ret void 146*9880d681SAndroid Build Coastguard WorkerL3: 147*9880d681SAndroid Build Coastguard Worker call void @foo() 148*9880d681SAndroid Build Coastguard Worker ret void 149*9880d681SAndroid Build Coastguard WorkerL4: 150*9880d681SAndroid Build Coastguard Worker call void @foo() 151*9880d681SAndroid Build Coastguard Worker 152*9880d681SAndroid Build Coastguard Worker; This keeps blockaddresses not otherwise listed as successors from being zapped 153*9880d681SAndroid Build Coastguard Worker; before SimplifyCFG even looks at the indirectbr. 154*9880d681SAndroid Build Coastguard Worker indirectbr i8* %anchor, [label %L1, label %L2] 155*9880d681SAndroid Build Coastguard Worker} 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Worker; The same as above, except the selected addresses are equal. 158*9880d681SAndroid Build Coastguard Worker 159*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @indbrtest6( 160*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 161*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: unreachable 162*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 163*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest6(i1 %cond, i8* %anchor) nounwind { 164*9880d681SAndroid Build Coastguard Workerentry: 165*9880d681SAndroid Build Coastguard Worker %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest6, %L1), i8* blockaddress(@indbrtest6, %L1) 166*9880d681SAndroid Build Coastguard Worker; This needs to have more than one successor for this test, otherwise it gets 167*9880d681SAndroid Build Coastguard Worker; replaced with an unconditional branch to the single successor. 168*9880d681SAndroid Build Coastguard Worker indirectbr i8* %indirect.goto.dest, [label %L2, label %L3] 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard WorkerL1: 171*9880d681SAndroid Build Coastguard Worker call void @A() 172*9880d681SAndroid Build Coastguard Worker ret void 173*9880d681SAndroid Build Coastguard WorkerL2: 174*9880d681SAndroid Build Coastguard Worker call void @C() 175*9880d681SAndroid Build Coastguard Worker ret void 176*9880d681SAndroid Build Coastguard WorkerL3: 177*9880d681SAndroid Build Coastguard Worker call void @foo() 178*9880d681SAndroid Build Coastguard Worker 179*9880d681SAndroid Build Coastguard Worker; This keeps blockaddresses not otherwise listed as successors from being zapped 180*9880d681SAndroid Build Coastguard Worker; before SimplifyCFG even looks at the indirectbr. 181*9880d681SAndroid Build Coastguard Worker indirectbr i8* %anchor, [label %L1, label %L2] 182*9880d681SAndroid Build Coastguard Worker} 183*9880d681SAndroid Build Coastguard Worker 184*9880d681SAndroid Build Coastguard Worker; PR10072 185*9880d681SAndroid Build Coastguard Worker 186*9880d681SAndroid Build Coastguard Worker@xblkx.bbs = internal unnamed_addr constant [9 x i8*] [i8* blockaddress(@indbrtest7, %xblkx.begin), i8* blockaddress(@indbrtest7, %xblkx.begin3), i8* blockaddress(@indbrtest7, %xblkx.begin4), i8* blockaddress(@indbrtest7, %xblkx.begin5), i8* blockaddress(@indbrtest7, %xblkx.begin6), i8* blockaddress(@indbrtest7, %xblkx.begin7), i8* blockaddress(@indbrtest7, %xblkx.begin8), i8* blockaddress(@indbrtest7, %xblkx.begin9), i8* blockaddress(@indbrtest7, %xblkx.end)] 187*9880d681SAndroid Build Coastguard Worker 188*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest7() { 189*9880d681SAndroid Build Coastguard Workerescape-string.top: 190*9880d681SAndroid Build Coastguard Worker %xval202x = call i32 @xfunc5x() 191*9880d681SAndroid Build Coastguard Worker br label %xlab5x 192*9880d681SAndroid Build Coastguard Worker 193*9880d681SAndroid Build Coastguard Workerxlab8x: ; preds = %xlab5x 194*9880d681SAndroid Build Coastguard Worker %xvaluex = call i32 @xselectorx() 195*9880d681SAndroid Build Coastguard Worker %xblkx.x = getelementptr [9 x i8*], [9 x i8*]* @xblkx.bbs, i32 0, i32 %xvaluex 196*9880d681SAndroid Build Coastguard Worker %xblkx.load = load i8*, i8** %xblkx.x 197*9880d681SAndroid Build Coastguard Worker indirectbr i8* %xblkx.load, [label %xblkx.begin, label %xblkx.begin3, label %xblkx.begin4, label %xblkx.begin5, label %xblkx.begin6, label %xblkx.begin7, label %xblkx.begin8, label %xblkx.begin9, label %xblkx.end] 198*9880d681SAndroid Build Coastguard Worker 199*9880d681SAndroid Build Coastguard Workerxblkx.begin: 200*9880d681SAndroid Build Coastguard Worker br label %xblkx.end 201*9880d681SAndroid Build Coastguard Worker 202*9880d681SAndroid Build Coastguard Workerxblkx.begin3: 203*9880d681SAndroid Build Coastguard Worker br label %xblkx.end 204*9880d681SAndroid Build Coastguard Worker 205*9880d681SAndroid Build Coastguard Workerxblkx.begin4: 206*9880d681SAndroid Build Coastguard Worker br label %xblkx.end 207*9880d681SAndroid Build Coastguard Worker 208*9880d681SAndroid Build Coastguard Workerxblkx.begin5: 209*9880d681SAndroid Build Coastguard Worker br label %xblkx.end 210*9880d681SAndroid Build Coastguard Worker 211*9880d681SAndroid Build Coastguard Workerxblkx.begin6: 212*9880d681SAndroid Build Coastguard Worker br label %xblkx.end 213*9880d681SAndroid Build Coastguard Worker 214*9880d681SAndroid Build Coastguard Workerxblkx.begin7: 215*9880d681SAndroid Build Coastguard Worker br label %xblkx.end 216*9880d681SAndroid Build Coastguard Worker 217*9880d681SAndroid Build Coastguard Workerxblkx.begin8: 218*9880d681SAndroid Build Coastguard Worker br label %xblkx.end 219*9880d681SAndroid Build Coastguard Worker 220*9880d681SAndroid Build Coastguard Workerxblkx.begin9: 221*9880d681SAndroid Build Coastguard Worker br label %xblkx.end 222*9880d681SAndroid Build Coastguard Worker 223*9880d681SAndroid Build Coastguard Workerxblkx.end: 224*9880d681SAndroid Build Coastguard Worker %yes.0 = phi i1 [ false, %xblkx.begin ], [ true, %xlab8x ], [ false, %xblkx.begin9 ], [ false, %xblkx.begin8 ], [ false, %xblkx.begin7 ], [ false, %xblkx.begin6 ], [ false, %xblkx.begin5 ], [ true, %xblkx.begin4 ], [ false, %xblkx.begin3 ] 225*9880d681SAndroid Build Coastguard Worker br i1 %yes.0, label %v2j, label %xlab17x 226*9880d681SAndroid Build Coastguard Worker 227*9880d681SAndroid Build Coastguard Workerv2j: 228*9880d681SAndroid Build Coastguard Worker; CHECK: %xunusedx = call i32 @xactionx() 229*9880d681SAndroid Build Coastguard Worker %xunusedx = call i32 @xactionx() 230*9880d681SAndroid Build Coastguard Worker br label %xlab4x 231*9880d681SAndroid Build Coastguard Worker 232*9880d681SAndroid Build Coastguard Workerxlab17x: 233*9880d681SAndroid Build Coastguard Worker br label %xlab4x 234*9880d681SAndroid Build Coastguard Worker 235*9880d681SAndroid Build Coastguard Workerxlab4x: 236*9880d681SAndroid Build Coastguard Worker %incr19 = add i32 %xval704x.0, 1 237*9880d681SAndroid Build Coastguard Worker br label %xlab5x 238*9880d681SAndroid Build Coastguard Worker 239*9880d681SAndroid Build Coastguard Workerxlab5x: 240*9880d681SAndroid Build Coastguard Worker %xval704x.0 = phi i32 [ 0, %escape-string.top ], [ %incr19, %xlab4x ] 241*9880d681SAndroid Build Coastguard Worker %xval10x = icmp ult i32 %xval704x.0, %xval202x 242*9880d681SAndroid Build Coastguard Worker br i1 %xval10x, label %xlab8x, label %xlab9x 243*9880d681SAndroid Build Coastguard Worker 244*9880d681SAndroid Build Coastguard Workerxlab9x: 245*9880d681SAndroid Build Coastguard Worker ret void 246*9880d681SAndroid Build Coastguard Worker} 247*9880d681SAndroid Build Coastguard Worker 248*9880d681SAndroid Build Coastguard Workerdeclare i32 @xfunc5x() 249*9880d681SAndroid Build Coastguard Workerdeclare i8 @xfunc7x() 250*9880d681SAndroid Build Coastguard Workerdeclare i32 @xselectorx() 251*9880d681SAndroid Build Coastguard Workerdeclare i32 @xactionx() 252