1; RUN: llc < %s -march=arm -mcpu=cortex-a8 -mattr=+vfp2 -enable-unsafe-fp-math | FileCheck %s 2; rdar://7461510 3; rdar://10964603 4 5; Disable this optimization unless we know one of them is zero. 6define arm_apcscc i32 @t1(float* %a, float* %b) nounwind { 7entry: 8; CHECK: t1: 9; CHECK: vldr [[S0:s[0-9]+]], 10; CHECK: vldr [[S1:s[0-9]+]], 11; CHECK: vcmpe.f32 [[S1]], [[S0]] 12; CHECK: vmrs APSR_nzcv, fpscr 13; CHECK: beq 14 %0 = load float* %a 15 %1 = load float* %b 16 %2 = fcmp une float %0, %1 17 br i1 %2, label %bb1, label %bb2 18 19bb1: 20 %3 = call i32 @bar() 21 ret i32 %3 22 23bb2: 24 %4 = call i32 @foo() 25 ret i32 %4 26} 27 28; If one side is zero, the other size sign bit is masked off to allow 29; +0.0 == -0.0 30define arm_apcscc i32 @t2(double* %a, double* %b) nounwind { 31entry: 32; CHECK: t2: 33; CHECK-NOT: vldr 34; CHECK: ldr [[REG1:(r[0-9]+)]], [r0] 35; CHECK: ldr [[REG2:(r[0-9]+)]], [r0, #4] 36; CHECK-NOT: b LBB 37; CHECK: cmp [[REG1]], #0 38; CHECK: bfc [[REG2]], #31, #1 39; CHECK: cmpeq [[REG2]], #0 40; CHECK-NOT: vcmpe.f32 41; CHECK-NOT: vmrs 42; CHECK: bne 43 %0 = load double* %a 44 %1 = fcmp oeq double %0, 0.000000e+00 45 br i1 %1, label %bb1, label %bb2 46 47bb1: 48 %2 = call i32 @bar() 49 ret i32 %2 50 51bb2: 52 %3 = call i32 @foo() 53 ret i32 %3 54} 55 56define arm_apcscc i32 @t3(float* %a, float* %b) nounwind { 57entry: 58; CHECK: t3: 59; CHECK-NOT: vldr 60; CHECK: ldr [[REG3:(r[0-9]+)]], [r0] 61; CHECK: mvn [[REG4:(r[0-9]+)]], #-2147483648 62; CHECK: tst [[REG3]], [[REG4]] 63; CHECK-NOT: vcmpe.f32 64; CHECK-NOT: vmrs 65; CHECK: bne 66 %0 = load float* %a 67 %1 = fcmp oeq float %0, 0.000000e+00 68 br i1 %1, label %bb1, label %bb2 69 70bb1: 71 %2 = call i32 @bar() 72 ret i32 %2 73 74bb2: 75 %3 = call i32 @foo() 76 ret i32 %3 77} 78 79declare i32 @bar() 80declare i32 @foo() 81