1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 2; RUN: opt %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s --check-prefixes=NORMAL,BASELINE 3; RUN: opt %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S -bonus-inst-threshold=2 | FileCheck %s --check-prefixes=NORMAL,AGGRESSIVE 4; RUN: opt %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S -bonus-inst-threshold=4 | FileCheck %s --check-prefixes=WAYAGGRESSIVE 5; RUN: opt %s -passes=simplifycfg -S | FileCheck %s --check-prefixes=NORMAL,BASELINE 6; RUN: opt %s -passes="simplifycfg<bonus-inst-threshold=2>" -S | FileCheck %s --check-prefixes=NORMAL,AGGRESSIVE 7; RUN: opt %s -passes="simplifycfg<bonus-inst-threshold=4>" -S | FileCheck %s --check-prefixes=WAYAGGRESSIVE 8 9define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d, ptr %input) { 10; BASELINE-LABEL: define i32 @foo( 11; BASELINE-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], ptr [[INPUT:%.*]]) { 12; BASELINE-NEXT: [[ENTRY:.*]]: 13; BASELINE-NEXT: [[CMP:%.*]] = icmp sgt i32 [[D]], 3 14; BASELINE-NEXT: br i1 [[CMP]], label %[[COND_END:.*]], label %[[LOR_LHS_FALSE:.*]] 15; BASELINE: [[LOR_LHS_FALSE]]: 16; BASELINE-NEXT: [[MUL:%.*]] = shl i32 [[C]], 1 17; BASELINE-NEXT: [[ADD:%.*]] = add nsw i32 [[MUL]], [[A]] 18; BASELINE-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B]] 19; BASELINE-NEXT: br i1 [[CMP1]], label %[[COND_FALSE:.*]], label %[[COND_END]] 20; BASELINE: [[COND_FALSE]]: 21; BASELINE-NEXT: [[TMP0:%.*]] = load i32, ptr [[INPUT]], align 4 22; BASELINE-NEXT: br label %[[COND_END]] 23; BASELINE: [[COND_END]]: 24; BASELINE-NEXT: [[COND:%.*]] = phi i32 [ [[TMP0]], %[[COND_FALSE]] ], [ 0, %[[LOR_LHS_FALSE]] ], [ 0, %[[ENTRY]] ] 25; BASELINE-NEXT: ret i32 [[COND]] 26; 27; AGGRESSIVE-LABEL: define i32 @foo( 28; AGGRESSIVE-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], ptr [[INPUT:%.*]]) { 29; AGGRESSIVE-NEXT: [[ENTRY:.*]]: 30; AGGRESSIVE-NEXT: [[CMP:%.*]] = icmp sle i32 [[D]], 3 31; AGGRESSIVE-NEXT: [[MUL:%.*]] = shl i32 [[C]], 1 32; AGGRESSIVE-NEXT: [[ADD:%.*]] = add nsw i32 [[MUL]], [[A]] 33; AGGRESSIVE-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B]] 34; AGGRESSIVE-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 [[CMP1]], i1 false 35; AGGRESSIVE-NEXT: br i1 [[OR_COND]], label %[[COND_FALSE:.*]], label %[[COND_END:.*]] 36; AGGRESSIVE: [[COND_FALSE]]: 37; AGGRESSIVE-NEXT: [[TMP0:%.*]] = load i32, ptr [[INPUT]], align 4 38; AGGRESSIVE-NEXT: br label %[[COND_END]] 39; AGGRESSIVE: [[COND_END]]: 40; AGGRESSIVE-NEXT: [[COND:%.*]] = phi i32 [ [[TMP0]], %[[COND_FALSE]] ], [ 0, %[[ENTRY]] ] 41; AGGRESSIVE-NEXT: ret i32 [[COND]] 42; 43; WAYAGGRESSIVE-LABEL: define i32 @foo( 44; WAYAGGRESSIVE-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], ptr [[INPUT:%.*]]) { 45; WAYAGGRESSIVE-NEXT: [[ENTRY:.*]]: 46; WAYAGGRESSIVE-NEXT: [[CMP:%.*]] = icmp sle i32 [[D]], 3 47; WAYAGGRESSIVE-NEXT: [[MUL:%.*]] = shl i32 [[C]], 1 48; WAYAGGRESSIVE-NEXT: [[ADD:%.*]] = add nsw i32 [[MUL]], [[A]] 49; WAYAGGRESSIVE-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B]] 50; WAYAGGRESSIVE-NEXT: [[OR_COND:%.*]] = select i1 [[CMP]], i1 [[CMP1]], i1 false 51; WAYAGGRESSIVE-NEXT: br i1 [[OR_COND]], label %[[COND_FALSE:.*]], label %[[COND_END:.*]] 52; WAYAGGRESSIVE: [[COND_FALSE]]: 53; WAYAGGRESSIVE-NEXT: [[TMP0:%.*]] = load i32, ptr [[INPUT]], align 4 54; WAYAGGRESSIVE-NEXT: br label %[[COND_END]] 55; WAYAGGRESSIVE: [[COND_END]]: 56; WAYAGGRESSIVE-NEXT: [[COND:%.*]] = phi i32 [ [[TMP0]], %[[COND_FALSE]] ], [ 0, %[[ENTRY]] ] 57; WAYAGGRESSIVE-NEXT: ret i32 [[COND]] 58; 59entry: 60 %cmp = icmp sgt i32 %d, 3 61 br i1 %cmp, label %cond.end, label %lor.lhs.false 62 63lor.lhs.false: 64 %mul = shl i32 %c, 1 65 %add = add nsw i32 %mul, %a 66 %cmp1 = icmp slt i32 %add, %b 67 br i1 %cmp1, label %cond.false, label %cond.end 68 69cond.false: 70 %0 = load i32, ptr %input, align 4 71 br label %cond.end 72 73cond.end: 74 %cond = phi i32 [ %0, %cond.false ], [ 0, %lor.lhs.false ], [ 0, %entry ] 75 ret i32 %cond 76} 77 78declare void @distinct_a(); 79declare void @distinct_b(); 80 81;; Like foo, but have to duplicate into multiple predecessors 82define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d, ptr %input) { 83; NORMAL-LABEL: define i32 @bar( 84; NORMAL-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], ptr [[INPUT:%.*]]) { 85; NORMAL-NEXT: [[ENTRY:.*:]] 86; NORMAL-NEXT: [[CMP_SPLIT:%.*]] = icmp slt i32 [[D]], [[B]] 87; NORMAL-NEXT: [[CMP:%.*]] = icmp sgt i32 [[D]], 3 88; NORMAL-NEXT: br i1 [[CMP_SPLIT]], label %[[PRED_A:.*]], label %[[PRED_B:.*]] 89; NORMAL: [[PRED_A]]: 90; NORMAL-NEXT: call void @distinct_a() 91; NORMAL-NEXT: br i1 [[CMP]], label %[[COND_END:.*]], label %[[LOR_LHS_FALSE:.*]] 92; NORMAL: [[PRED_B]]: 93; NORMAL-NEXT: call void @distinct_b() 94; NORMAL-NEXT: br i1 [[CMP]], label %[[COND_END]], label %[[LOR_LHS_FALSE]] 95; NORMAL: [[LOR_LHS_FALSE]]: 96; NORMAL-NEXT: [[MUL:%.*]] = shl i32 [[C]], 1 97; NORMAL-NEXT: [[ADD:%.*]] = add nsw i32 [[MUL]], [[A]] 98; NORMAL-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B]] 99; NORMAL-NEXT: br i1 [[CMP1]], label %[[COND_FALSE:.*]], label %[[COND_END]] 100; NORMAL: [[COND_FALSE]]: 101; NORMAL-NEXT: [[TMP0:%.*]] = load i32, ptr [[INPUT]], align 4 102; NORMAL-NEXT: br label %[[COND_END]] 103; NORMAL: [[COND_END]]: 104; NORMAL-NEXT: [[COND:%.*]] = phi i32 [ [[TMP0]], %[[COND_FALSE]] ], [ 0, %[[LOR_LHS_FALSE]] ], [ 0, %[[PRED_A]] ], [ 0, %[[PRED_B]] ] 105; NORMAL-NEXT: ret i32 [[COND]] 106; 107; WAYAGGRESSIVE-LABEL: define i32 @bar( 108; WAYAGGRESSIVE-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], ptr [[INPUT:%.*]]) { 109; WAYAGGRESSIVE-NEXT: [[ENTRY:.*:]] 110; WAYAGGRESSIVE-NEXT: [[CMP_SPLIT:%.*]] = icmp slt i32 [[D]], [[B]] 111; WAYAGGRESSIVE-NEXT: [[CMP:%.*]] = icmp sgt i32 [[D]], 3 112; WAYAGGRESSIVE-NEXT: br i1 [[CMP_SPLIT]], label %[[PRED_A:.*]], label %[[PRED_B:.*]] 113; WAYAGGRESSIVE: [[PRED_A]]: 114; WAYAGGRESSIVE-NEXT: call void @distinct_a() 115; WAYAGGRESSIVE-NEXT: [[CMP_NOT1:%.*]] = xor i1 [[CMP]], true 116; WAYAGGRESSIVE-NEXT: [[MUL_OLD:%.*]] = shl i32 [[C]], 1 117; WAYAGGRESSIVE-NEXT: [[ADD_OLD:%.*]] = add nsw i32 [[MUL_OLD]], [[A]] 118; WAYAGGRESSIVE-NEXT: [[CMP1_OLD:%.*]] = icmp slt i32 [[ADD_OLD]], [[B]] 119; WAYAGGRESSIVE-NEXT: [[OR_COND2:%.*]] = select i1 [[CMP_NOT1]], i1 [[CMP1_OLD]], i1 false 120; WAYAGGRESSIVE-NEXT: br i1 [[OR_COND2]], label %[[COND_FALSE:.*]], label %[[COND_END:.*]] 121; WAYAGGRESSIVE: [[PRED_B]]: 122; WAYAGGRESSIVE-NEXT: call void @distinct_b() 123; WAYAGGRESSIVE-NEXT: [[CMP_NOT:%.*]] = xor i1 [[CMP]], true 124; WAYAGGRESSIVE-NEXT: [[MUL:%.*]] = shl i32 [[C]], 1 125; WAYAGGRESSIVE-NEXT: [[ADD:%.*]] = add nsw i32 [[MUL]], [[A]] 126; WAYAGGRESSIVE-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ADD]], [[B]] 127; WAYAGGRESSIVE-NEXT: [[OR_COND:%.*]] = select i1 [[CMP_NOT]], i1 [[CMP1]], i1 false 128; WAYAGGRESSIVE-NEXT: br i1 [[OR_COND]], label %[[COND_FALSE]], label %[[COND_END]] 129; WAYAGGRESSIVE: [[COND_FALSE]]: 130; WAYAGGRESSIVE-NEXT: [[TMP0:%.*]] = load i32, ptr [[INPUT]], align 4 131; WAYAGGRESSIVE-NEXT: br label %[[COND_END]] 132; WAYAGGRESSIVE: [[COND_END]]: 133; WAYAGGRESSIVE-NEXT: [[COND:%.*]] = phi i32 [ [[TMP0]], %[[COND_FALSE]] ], [ 0, %[[PRED_A]] ], [ 0, %[[PRED_B]] ] 134; WAYAGGRESSIVE-NEXT: ret i32 [[COND]] 135; 136entry: 137 %cmp_split = icmp slt i32 %d, %b 138 %cmp = icmp sgt i32 %d, 3 139 br i1 %cmp_split, label %pred_a, label %pred_b 140 141pred_a: 142 call void @distinct_a(); 143 br i1 %cmp, label %cond.end, label %lor.lhs.false 144 145pred_b: 146 call void @distinct_b(); 147 br i1 %cmp, label %cond.end, label %lor.lhs.false 148 149lor.lhs.false: 150 %mul = shl i32 %c, 1 151 %add = add nsw i32 %mul, %a 152 %cmp1 = icmp slt i32 %add, %b 153 br i1 %cmp1, label %cond.false, label %cond.end 154 155cond.false: 156 %0 = load i32, ptr %input, align 4 157 br label %cond.end 158 159cond.end: 160 %cond = phi i32 [ %0, %cond.false ], [ 0, %lor.lhs.false ],[ 0, %pred_a ],[ 0, %pred_b ] 161 ret i32 %cond 162} 163