1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s 3 4; Test that we can thread a simple known condition through switch statements. 5 6declare void @foo1() 7 8declare void @foo2() 9 10declare void @DEAD() 11 12define void @test1(i32 %V) { 13; CHECK-LABEL: @test1( 14; CHECK-NEXT: switch i32 [[V:%.*]], label [[A:%.*]] [ 15; CHECK-NEXT: i32 4, label [[T:%.*]] 16; CHECK-NEXT: i32 17, label [[COMMON_RET:%.*]] 17; CHECK-NEXT: ] 18; CHECK: T: 19; CHECK-NEXT: call void @foo1() 20; CHECK-NEXT: call void @foo2() 21; CHECK-NEXT: br label [[COMMON_RET]] 22; CHECK: A: 23; CHECK-NEXT: call void @foo1() 24; CHECK-NEXT: br label [[COMMON_RET]] 25; CHECK: common.ret: 26; CHECK-NEXT: ret void 27; 28 switch i32 %V, label %A [ 29 i32 4, label %T 30 i32 17, label %Done 31 i32 1234, label %A 32 ] 33;; V == 4 if we get here. 34T: ; preds = %0 35 call void @foo1( ) 36 ;; This switch is always statically determined. 37 switch i32 %V, label %A2 [ 38 i32 4, label %B 39 i32 17, label %C 40 i32 42, label %C 41 ] 42A2: ; preds = %T 43 call void @DEAD( ) 44 call void @DEAD( ) 45 ;; always true 46 %cond2 = icmp eq i32 %V, 4 ; <i1> [#uses=1] 47 br i1 %cond2, label %Done, label %C 48A: ; preds = %0, %0 49 call void @foo1( ) 50 ;; always true 51 %cond = icmp ne i32 %V, 4 ; <i1> [#uses=1] 52 br i1 %cond, label %Done, label %C 53Done: ; preds = %B, %A, %A2, %0 54 ret void 55B: ; preds = %T 56 call void @foo2( ) 57 ;; always true 58 %cond3 = icmp eq i32 %V, 4 ; <i1> [#uses=1] 59 br i1 %cond3, label %Done, label %C 60C: ; preds = %B, %A, %A2, %T, %T 61 call void @DEAD( ) 62 ret void 63 64} 65 66define void @test2(i32 %V) { 67; CHECK-LABEL: @test2( 68; CHECK-NEXT: switch i32 [[V:%.*]], label [[A:%.*]] [ 69; CHECK-NEXT: i32 4, label [[T:%.*]] 70; CHECK-NEXT: i32 17, label [[D:%.*]] 71; CHECK-NEXT: i32 1234, label [[COMMON_RET:%.*]] 72; CHECK-NEXT: ] 73; CHECK: A: 74; CHECK-NEXT: call void @foo1() 75; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[V]], 42 76; CHECK-NEXT: br i1 [[COND]], label [[D]], label [[COMMON_RET]] 77; CHECK: common.ret: 78; CHECK-NEXT: ret void 79; CHECK: T: 80; CHECK-NEXT: call void @foo1() 81; CHECK-NEXT: call void @foo1() 82; CHECK-NEXT: br label [[COMMON_RET]] 83; CHECK: D: 84; CHECK-NEXT: call void @foo1() 85; CHECK-NEXT: br label [[COMMON_RET]] 86; 87 switch i32 %V, label %A [ 88 i32 4, label %T 89 i32 17, label %D 90 i32 1234, label %E 91 ] 92;; V != 4, 17, 1234 here. 93A: ; preds = %0 94 call void @foo1( ) 95 ;; This switch is always statically determined. 96 switch i32 %V, label %E [ 97 i32 4, label %C 98 i32 17, label %C 99 i32 42, label %D 100 ] 101;; unreacahble. 102C: ; preds = %A, %A 103 call void @DEAD( ) 104 ret void 105T: ; preds = %0 106 call void @foo1( ) 107 call void @foo1( ) 108 ret void 109D: ; preds = %A, %0 110 call void @foo1( ) 111 ret void 112E: ; preds = %A, %0 113 ret void 114 115} 116 117