1; RUN: opt -gvn -S < %s | FileCheck %s 2 3define i32 @f1(i32 %x) { 4 ; CHECK-LABEL: define i32 @f1( 5bb0: 6 %cmp = icmp eq i32 %x, 0 7 br i1 %cmp, label %bb2, label %bb1 8bb1: 9 br label %bb2 10bb2: 11 %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ] 12 %foo = add i32 %cond, %x 13 ret i32 %foo 14 ; CHECK: bb2: 15 ; CHECK: ret i32 %x 16} 17 18define i32 @f2(i32 %x) { 19 ; CHECK-LABEL: define i32 @f2( 20bb0: 21 %cmp = icmp ne i32 %x, 0 22 br i1 %cmp, label %bb1, label %bb2 23bb1: 24 br label %bb2 25bb2: 26 %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ] 27 %foo = add i32 %cond, %x 28 ret i32 %foo 29 ; CHECK: bb2: 30 ; CHECK: ret i32 %x 31} 32 33define i32 @f3(i32 %x) { 34 ; CHECK-LABEL: define i32 @f3( 35bb0: 36 switch i32 %x, label %bb1 [ i32 0, label %bb2] 37bb1: 38 br label %bb2 39bb2: 40 %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ] 41 %foo = add i32 %cond, %x 42 ret i32 %foo 43 ; CHECK: bb2: 44 ; CHECK: ret i32 %x 45} 46 47declare void @g(i1) 48define void @f4(i8 * %x) { 49; CHECK-LABEL: define void @f4( 50bb0: 51 %y = icmp eq i8* null, %x 52 br i1 %y, label %bb2, label %bb1 53bb1: 54 br label %bb2 55bb2: 56 %zed = icmp eq i8* null, %x 57 call void @g(i1 %zed) 58; CHECK: call void @g(i1 %y) 59 ret void 60} 61 62define double @fcmp_oeq_not_zero(double %x, double %y) { 63entry: 64 %cmp = fcmp oeq double %y, 2.0 65 br i1 %cmp, label %if, label %return 66 67if: 68 %div = fdiv double %x, %y 69 br label %return 70 71return: 72 %retval = phi double [ %div, %if ], [ %x, %entry ] 73 ret double %retval 74 75; CHECK-LABEL: define double @fcmp_oeq_not_zero( 76; CHECK: %div = fdiv double %x, 2.0 77} 78 79define double @fcmp_une_not_zero(double %x, double %y) { 80entry: 81 %cmp = fcmp une double %y, 2.0 82 br i1 %cmp, label %return, label %else 83 84else: 85 %div = fdiv double %x, %y 86 br label %return 87 88return: 89 %retval = phi double [ %div, %else ], [ %x, %entry ] 90 ret double %retval 91 92; CHECK-LABEL: define double @fcmp_une_not_zero( 93; CHECK: %div = fdiv double %x, 2.0 94} 95 96; PR22376 - We can't propagate zero constants because -0.0 97; compares equal to 0.0. If %y is -0.0 in this test case, 98; we would produce the wrong sign on the infinity return value. 99define double @fcmp_oeq_zero(double %x, double %y) { 100entry: 101 %cmp = fcmp oeq double %y, 0.0 102 br i1 %cmp, label %if, label %return 103 104if: 105 %div = fdiv double %x, %y 106 br label %return 107 108return: 109 %retval = phi double [ %div, %if ], [ %x, %entry ] 110 ret double %retval 111 112; CHECK-LABEL: define double @fcmp_oeq_zero( 113; CHECK: %div = fdiv double %x, %y 114} 115 116define double @fcmp_une_zero(double %x, double %y) { 117entry: 118 %cmp = fcmp une double %y, -0.0 119 br i1 %cmp, label %return, label %else 120 121else: 122 %div = fdiv double %x, %y 123 br label %return 124 125return: 126 %retval = phi double [ %div, %else ], [ %x, %entry ] 127 ret double %retval 128 129; CHECK-LABEL: define double @fcmp_une_zero( 130; CHECK: %div = fdiv double %x, %y 131} 132 133; We also cannot propagate a value if it's not a constant. 134; This is because the value could be 0.0 or -0.0. 135 136define double @fcmp_oeq_maybe_zero(double %x, double %y, double %z1, double %z2) { 137entry: 138 %z = fadd double %z1, %z2 139 %cmp = fcmp oeq double %y, %z 140 br i1 %cmp, label %if, label %return 141 142if: 143 %div = fdiv double %x, %z 144 br label %return 145 146return: 147 %retval = phi double [ %div, %if ], [ %x, %entry ] 148 ret double %retval 149 150; CHECK-LABEL: define double @fcmp_oeq_maybe_zero( 151; CHECK: %div = fdiv double %x, %z 152} 153 154define double @fcmp_une_maybe_zero(double %x, double %y, double %z1, double %z2) { 155entry: 156 %z = fadd double %z1, %z2 157 %cmp = fcmp une double %y, %z 158 br i1 %cmp, label %return, label %else 159 160else: 161 %div = fdiv double %x, %z 162 br label %return 163 164return: 165 %retval = phi double [ %div, %else ], [ %x, %entry ] 166 ret double %retval 167 168; CHECK-LABEL: define double @fcmp_une_maybe_zero( 169; CHECK: %div = fdiv double %x, %z 170} 171