1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt %s -S -o - -passes=simplifycfg | FileCheck %s 3 4%struct.S = type { [4 x i32] } 5 6; Check the second, third, and fourth basic blocks are folded into 7; the first basic block since each has one bonus intruction, which 8; does not exceed the default bouns instruction threshold of 1. 9 10define i1 @test1(i32 %0, i32 %1, i32 %2, i32 %3) { 11; CHECK-LABEL: @test1( 12; CHECK-NEXT: entry: 13; CHECK-NEXT: [[MUL0:%.*]] = mul i32 [[TMP0:%.*]], [[TMP0]] 14; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[MUL0]], 0 15; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[TMP1:%.*]], [[TMP1]] 16; CHECK-NEXT: [[CMP2_1:%.*]] = icmp sgt i32 [[MUL1]], 0 17; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP2]], i1 true, i1 [[CMP2_1]] 18; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[TMP2:%.*]], [[TMP2]] 19; CHECK-NEXT: [[CMP2_2:%.*]] = icmp sgt i32 [[MUL2]], 0 20; CHECK-NEXT: [[OR_COND1:%.*]] = select i1 [[OR_COND]], i1 true, i1 [[CMP2_2]] 21; CHECK-NEXT: [[MUL3:%.*]] = mul i32 [[TMP3:%.*]], [[TMP3]] 22; CHECK-NEXT: [[CMP2_3:%.*]] = icmp sgt i32 [[MUL3]], 0 23; CHECK-NEXT: [[OR_COND2:%.*]] = select i1 [[OR_COND1]], i1 true, i1 [[CMP2_3]] 24; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[OR_COND2]], i1 false, i1 true 25; CHECK-NEXT: ret i1 [[SPEC_SELECT]] 26; 27entry: 28 %mul0 = mul i32 %0, %0 29 %cmp2 = icmp sgt i32 %mul0, 0 30 br i1 %cmp2, label %cleanup, label %for.cond 31 32for.cond: 33 %mul1 = mul i32 %1, %1 34 %cmp2.1 = icmp sgt i32 %mul1, 0 35 br i1 %cmp2.1, label %cleanup, label %for.cond.1 36 37for.cond.1: 38 %mul2 = mul i32 %2, %2 39 %cmp2.2 = icmp sgt i32 %mul2, 0 40 br i1 %cmp2.2, label %cleanup, label %for.cond.2 41 42for.cond.2: 43 %mul3 = mul i32 %3, %3 44 %cmp2.3 = icmp sgt i32 %mul3, 0 45 br i1 %cmp2.3, label %cleanup, label %for.cond.3 46 47for.cond.3: 48 br label %cleanup 49 50cleanup: 51 %cmp = phi i1 [ false, %entry ], [ false, %for.cond ], [ false, %for.cond.1 ], [ false, %for.cond.2 ], [ true, %for.cond.3 ] 52 ret i1 %cmp 53} 54 55; Check the second, third, and forth basic blocks are folded into the first 56; basic block since each has no bonus instruction. 57 58define i1 @test2(i32 %0, i32 %1, i32 %2, i32 %3) { 59; CHECK-LABEL: @test2( 60; CHECK-NEXT: entry: 61; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[TMP0:%.*]], 0 62; CHECK-NEXT: [[CMP2_1:%.*]] = icmp sgt i32 [[TMP1:%.*]], 0 63; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP2]], i1 true, i1 [[CMP2_1]] 64; CHECK-NEXT: [[CMP2_2:%.*]] = icmp sgt i32 [[TMP2:%.*]], 0 65; CHECK-NEXT: [[OR_COND1:%.*]] = select i1 [[OR_COND]], i1 true, i1 [[CMP2_2]] 66; CHECK-NEXT: [[CMP2_3:%.*]] = icmp sgt i32 [[TMP3:%.*]], 0 67; CHECK-NEXT: [[OR_COND2:%.*]] = select i1 [[OR_COND1]], i1 true, i1 [[CMP2_3]] 68; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[OR_COND2]], i1 false, i1 true 69; CHECK-NEXT: ret i1 [[SPEC_SELECT]] 70; 71entry: 72 %cmp2 = icmp sgt i32 %0, 0 73 br i1 %cmp2, label %cleanup, label %for.cond 74 75for.cond: 76 %cmp2.1 = icmp sgt i32 %1, 0 77 br i1 %cmp2.1, label %cleanup, label %for.cond.1 78 79for.cond.1: 80 %cmp2.2 = icmp sgt i32 %2, 0 81 br i1 %cmp2.2, label %cleanup, label %for.cond.2 82 83for.cond.2: 84 %cmp2.3 = icmp sgt i32 %3, 0 85 br i1 %cmp2.3, label %cleanup, label %for.cond.3 86 87for.cond.3: 88 br label %cleanup 89 90cleanup: 91 %cmp = phi i1 [ false, %entry ], [ false, %for.cond ], [ false, %for.cond.1 ], [ false, %for.cond.2 ], [ true, %for.cond.3 ] 92 ret i1 %cmp 93} 94 95; Check the second basic block is not folded into the first basic block 96; since it has three bonus instructions, which exceeds the default bonus 97; instruction threshold of 1. The third and fourth basic blocks are folded 98; into the second basic block since they do not have bonus instruction. 99 100define i1 @test3(i32 %0, i32 %1, i32 %2, i32 %3) { 101; CHECK-LABEL: @test3( 102; CHECK-NEXT: entry: 103; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[TMP0:%.*]], 0 104; CHECK-NEXT: br i1 [[CMP2]], label [[CLEANUP:%.*]], label [[FOR_COND:%.*]] 105; CHECK: for.cond: 106; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[TMP0]], [[TMP1:%.*]] 107; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[MUL1]], [[TMP2:%.*]] 108; CHECK-NEXT: [[MUL3:%.*]] = mul i32 [[MUL2]], [[TMP3:%.*]] 109; CHECK-NEXT: [[MUL4:%.*]] = mul i32 [[MUL3]], [[TMP3]] 110; CHECK-NEXT: [[MUL5:%.*]] = mul i32 [[MUL4]], [[TMP3]] 111; CHECK-NEXT: [[MUL6:%.*]] = mul i32 [[MUL5]], [[TMP3]] 112; CHECK-NEXT: [[CMP2_1:%.*]] = icmp sgt i32 [[MUL5]], 0 113; CHECK-NEXT: [[CMP2_2:%.*]] = icmp sgt i32 [[TMP2]], 0 114; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[CMP2_1]], i1 true, i1 [[CMP2_2]] 115; CHECK-NEXT: [[CMP2_3:%.*]] = icmp sgt i32 [[TMP3]], 0 116; CHECK-NEXT: [[OR_COND1:%.*]] = select i1 [[OR_COND]], i1 true, i1 [[CMP2_3]] 117; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[OR_COND1]], i1 false, i1 true 118; CHECK-NEXT: br label [[CLEANUP]] 119; CHECK: cleanup: 120; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[FOR_COND]] ] 121; CHECK-NEXT: ret i1 [[CMP]] 122; 123entry: 124 %cmp2 = icmp sgt i32 %0, 0 125 br i1 %cmp2, label %cleanup, label %for.cond 126 127for.cond: 128 %mul1 = mul i32 %0, %1 129 %mul2 = mul i32 %mul1, %2 130 %mul3 = mul i32 %mul2, %3 131 %mul4 = mul i32 %mul3, %3 132 %mul5 = mul i32 %mul4, %3 133 %mul6 = mul i32 %mul5, %3 134 %cmp2.1 = icmp sgt i32 %mul5, 0 135 br i1 %cmp2.1, label %cleanup, label %for.cond.1 136 137for.cond.1: 138 %cmp2.2 = icmp sgt i32 %2, 0 139 br i1 %cmp2.2, label %cleanup, label %for.cond.2 140 141for.cond.2: 142 %cmp2.3 = icmp sgt i32 %3, 0 143 br i1 %cmp2.3, label %cleanup, label %for.cond.3 144 145for.cond.3: 146 br label %cleanup 147 148cleanup: 149 %cmp = phi i1 [ false, %entry ], [ false, %for.cond ], [ false, %for.cond.1 ], [ false, %for.cond.2 ], [ true, %for.cond.3 ] 150 ret i1 %cmp 151} 152