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 96define double @fcmp_one_possibly_nan(double %x, double %y) { 97entry: 98 %cmp = fcmp one double %y, 2.0 99 br i1 %cmp, label %return, label %else 100 101else: 102 %div = fdiv double %x, %y 103 br label %return 104 105return: 106 %retval = phi double [ %div, %else ], [ %x, %entry ] 107 ret double %retval 108 109; CHECK-LABEL: define double @fcmp_one_possibly_nan( 110; CHECK: %div = fdiv double %x, %y 111} 112 113define double @fcmp_one_not_zero_or_nan(double %x, double %y) { 114entry: 115 %cmp = fcmp nnan one double %y, 2.0 116 br i1 %cmp, label %return, label %else 117 118else: 119 %div = fdiv double %x, %y 120 br label %return 121 122return: 123 %retval = phi double [ %div, %else ], [ %x, %entry ] 124 ret double %retval 125 126; CHECK-LABEL: define double @fcmp_one_not_zero_or_nan( 127; CHECK: %div = fdiv double %x, 2.0 128} 129 130; PR22376 - We can't propagate zero constants because -0.0 131; compares equal to 0.0. If %y is -0.0 in this test case, 132; we would produce the wrong sign on the infinity return value. 133define double @fcmp_oeq_zero(double %x, double %y) { 134entry: 135 %cmp = fcmp oeq double %y, 0.0 136 br i1 %cmp, label %if, label %return 137 138if: 139 %div = fdiv double %x, %y 140 br label %return 141 142return: 143 %retval = phi double [ %div, %if ], [ %x, %entry ] 144 ret double %retval 145 146; CHECK-LABEL: define double @fcmp_oeq_zero( 147; CHECK: %div = fdiv double %x, %y 148} 149 150define double @fcmp_une_zero(double %x, double %y) { 151entry: 152 %cmp = fcmp une double %y, -0.0 153 br i1 %cmp, label %return, label %else 154 155else: 156 %div = fdiv double %x, %y 157 br label %return 158 159return: 160 %retval = phi double [ %div, %else ], [ %x, %entry ] 161 ret double %retval 162 163; CHECK-LABEL: define double @fcmp_une_zero( 164; CHECK: %div = fdiv double %x, %y 165} 166 167; We also cannot propagate a value if it's not a constant. 168; This is because the value could be 0.0 or -0.0. 169 170define double @fcmp_oeq_maybe_zero(double %x, double %y, double %z1, double %z2) { 171entry: 172 %z = fadd double %z1, %z2 173 %cmp = fcmp oeq double %y, %z 174 br i1 %cmp, label %if, label %return 175 176if: 177 %div = fdiv double %x, %z 178 br label %return 179 180return: 181 %retval = phi double [ %div, %if ], [ %x, %entry ] 182 ret double %retval 183 184; CHECK-LABEL: define double @fcmp_oeq_maybe_zero( 185; CHECK: %div = fdiv double %x, %z 186} 187 188define double @fcmp_une_maybe_zero(double %x, double %y, double %z1, double %z2) { 189entry: 190 %z = fadd double %z1, %z2 191 %cmp = fcmp une double %y, %z 192 br i1 %cmp, label %return, label %else 193 194else: 195 %div = fdiv double %x, %z 196 br label %return 197 198return: 199 %retval = phi double [ %div, %else ], [ %x, %entry ] 200 ret double %retval 201 202; CHECK-LABEL: define double @fcmp_une_maybe_zero( 203; CHECK: %div = fdiv double %x, %z 204} 205 206 207define double @fcmp_ueq_possibly_nan(double %x, double %y) { 208entry: 209 %cmp = fcmp ueq double %y, 2.0 210 br i1 %cmp, label %do_div, label %return 211 212do_div: 213 %div = fdiv double %x, %y 214 br label %return 215 216return: 217 %retval = phi double [ %div, %do_div ], [ %x, %entry ] 218 ret double %retval 219 220; CHECK-LABEL: define double @fcmp_ueq_possibly_nan( 221; CHECK: %div = fdiv double %x, %y 222} 223 224define double @fcmp_ueq_not_zero_or_nan(double %x, double %y) { 225entry: 226 %cmp = fcmp nnan ueq double %y, 2.0 227 br i1 %cmp, label %do_div, label %return 228 229do_div: 230 %div = fdiv double %x, %y 231 br label %return 232 233return: 234 %retval = phi double [ %div, %do_div ], [ %x, %entry ] 235 ret double %retval 236 237; CHECK-LABEL: define double @fcmp_ueq_not_zero_or_nan( 238; CHECK: %div = fdiv double %x, 2.0 239} 240