1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -simplifycfg -S | FileCheck -enable-var-scope %s 3 4; Test basic folding to a conditional branch. 5define i32 @foo(i64 %x, i64 %y) nounwind { 6; CHECK-LABEL: @foo( 7; CHECK-NEXT: entry: 8; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]] 9; CHECK-NEXT: br i1 [[EQ]], label [[B:%.*]], label [[SWITCH:%.*]] 10; CHECK: switch: 11; CHECK-NEXT: [[LT:%.*]] = icmp slt i64 [[X]], [[Y]] 12; CHECK-NEXT: br i1 [[LT]], label [[A:%.*]], label [[B]] 13; CHECK: a: 14; CHECK-NEXT: tail call void @bees.a() #0 15; CHECK-NEXT: ret i32 1 16; CHECK: b: 17; CHECK-NEXT: [[RETVAL:%.*]] = phi i32 [ 0, [[SWITCH]] ], [ 2, [[ENTRY:%.*]] ] 18; CHECK-NEXT: tail call void @bees.b() #0 19; CHECK-NEXT: ret i32 [[RETVAL]] 20; 21entry: 22 %eq = icmp eq i64 %x, %y 23 br i1 %eq, label %b, label %switch 24switch: 25 %lt = icmp slt i64 %x, %y 26 %qux = select i1 %lt, i32 0, i32 2 27 switch i32 %qux, label %bees [ 28 i32 0, label %a 29 i32 1, label %b 30 i32 2, label %b 31 ] 32a: 33 tail call void @bees.a() nounwind 34 ret i32 1 35b: 36 %retval = phi i32 [0, %switch], [0, %switch], [2, %entry] 37 tail call void @bees.b() nounwind 38 ret i32 %retval 39bees: 40 tail call void @llvm.trap() nounwind 41 unreachable 42} 43 44; Test basic folding to an unconditional branch. 45define i32 @bar(i64 %x, i64 %y) nounwind { 46; CHECK-LABEL: @bar( 47; CHECK-NEXT: entry: 48; CHECK-NEXT: tail call void @bees.a() #0 49; CHECK-NEXT: ret i32 0 50; 51entry: 52 %lt = icmp slt i64 %x, %y 53 %qux = select i1 %lt, i32 0, i32 2 54 switch i32 %qux, label %bees [ 55 i32 0, label %a 56 i32 1, label %b 57 i32 2, label %a 58 ] 59a: 60 %retval = phi i32 [0, %entry], [0, %entry], [1, %b] 61 tail call void @bees.a() nounwind 62 ret i32 0 63b: 64 tail call void @bees.b() nounwind 65 br label %a 66bees: 67 tail call void @llvm.trap() nounwind 68 unreachable 69} 70 71; Test the edge case where both values from the select are the default case. 72define void @bazz(i64 %x, i64 %y) nounwind { 73; CHECK-LABEL: @bazz( 74; CHECK-NEXT: entry: 75; CHECK-NEXT: tail call void @bees.b() #0 76; CHECK-NEXT: ret void 77; 78entry: 79 %lt = icmp slt i64 %x, %y 80 %qux = select i1 %lt, i32 10, i32 12 81 switch i32 %qux, label %b [ 82 i32 0, label %a 83 i32 1, label %bees 84 i32 2, label %bees 85 ] 86a: 87 tail call void @bees.a() nounwind 88 ret void 89b: 90 tail call void @bees.b() nounwind 91 ret void 92bees: 93 tail call void @llvm.trap() 94 unreachable 95} 96 97; Test the edge case where both values from the select are equal. 98define void @quux(i64 %x, i64 %y) nounwind { 99; CHECK-LABEL: @quux( 100; CHECK-NEXT: entry: 101; CHECK-NEXT: tail call void @bees.a() #0 102; CHECK-NEXT: ret void 103; 104entry: 105 %lt = icmp slt i64 %x, %y 106 %qux = select i1 %lt, i32 0, i32 0 107 switch i32 %qux, label %b [ 108 i32 0, label %a 109 i32 1, label %bees 110 i32 2, label %bees 111 ] 112a: 113 tail call void @bees.a() nounwind 114 ret void 115b: 116 tail call void @bees.b() nounwind 117 ret void 118bees: 119 tail call void @llvm.trap() 120 unreachable 121} 122 123; A final test, for phi node munging. 124define i32 @xyzzy(i64 %x, i64 %y) { 125; CHECK-LABEL: @xyzzy( 126; CHECK-NEXT: entry: 127; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]] 128; CHECK-NEXT: [[LT:%.*]] = icmp slt i64 [[X]], [[Y]] 129; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[LT]], i32 -1, i32 1 130; CHECK-NEXT: [[VAL:%.*]] = select i1 [[EQ]], i32 0, i32 [[SPEC_SELECT]] 131; CHECK-NEXT: ret i32 [[VAL]] 132; 133entry: 134 %eq = icmp eq i64 %x, %y 135 br i1 %eq, label %r, label %cont 136cont: 137 %lt = icmp slt i64 %x, %y 138 %qux = select i1 %lt, i32 0, i32 2 139 switch i32 %qux, label %bees [ 140 i32 0, label %a 141 i32 1, label %r 142 i32 2, label %r 143 ] 144r: 145 %val = phi i32 [0, %entry], [1, %cont], [1, %cont] 146 ret i32 %val 147a: 148 ret i32 -1 149bees: 150 tail call void @llvm.trap() 151 unreachable 152} 153 154declare void @llvm.trap() nounwind noreturn 155declare void @bees.a() nounwind 156declare void @bees.b() nounwind 157 158; CHECK: attributes #1 = { cold noreturn nounwind } 159