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