1; RUN: llc -verify-machineinstrs -o - %s -mtriple=aarch64-none-linux-gnu -fp-contract=fast | FileCheck %s 2; RUN: llc -verify-machineinstrs -o - %s -mtriple=arm64-apple-ios7.0 | FileCheck %s -check-prefix=CHECK-NOFAST 3 4declare float @llvm.fma.f32(float, float, float) 5declare double @llvm.fma.f64(double, double, double) 6 7define float @test_fmadd(float %a, float %b, float %c) { 8; CHECK-LABEL: test_fmadd: 9; CHECK-NOFAST-LABEL: test_fmadd: 10 %val = call float @llvm.fma.f32(float %a, float %b, float %c) 11; CHECK: fmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 12; CHECK-NOFAST: fmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 13 ret float %val 14} 15 16define float @test_fmsub(float %a, float %b, float %c) { 17; CHECK-LABEL: test_fmsub: 18; CHECK-NOFAST-LABEL: test_fmsub: 19 %nega = fsub float -0.0, %a 20 %val = call float @llvm.fma.f32(float %nega, float %b, float %c) 21; CHECK: fmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 22; CHECK-NOFAST: fmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 23 ret float %val 24} 25 26define float @test_fnmadd(float %a, float %b, float %c) { 27; CHECK-LABEL: test_fnmadd: 28; CHECK-NOFAST-LABEL: test_fnmadd: 29 %nega = fsub float -0.0, %a 30 %negc = fsub float -0.0, %c 31 %val = call float @llvm.fma.f32(float %nega, float %b, float %negc) 32; CHECK: fnmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 33; CHECK-NOFAST: fnmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 34 ret float %val 35} 36 37define float @test_fnmsub(float %a, float %b, float %c) { 38; CHECK-LABEL: test_fnmsub: 39; CHECK-NOFAST-LABEL: test_fnmsub: 40 %negc = fsub float -0.0, %c 41 %val = call float @llvm.fma.f32(float %a, float %b, float %negc) 42; CHECK: fnmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 43; CHECK-NOFAST: fnmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 44 ret float %val 45} 46 47define double @testd_fmadd(double %a, double %b, double %c) { 48; CHECK-LABEL: testd_fmadd: 49; CHECK-NOFAST-LABEL: testd_fmadd: 50 %val = call double @llvm.fma.f64(double %a, double %b, double %c) 51; CHECK: fmadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} 52; CHECK-NOFAST: fmadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} 53 ret double %val 54} 55 56define double @testd_fmsub(double %a, double %b, double %c) { 57; CHECK-LABEL: testd_fmsub: 58; CHECK-NOFAST-LABEL: testd_fmsub: 59 %nega = fsub double -0.0, %a 60 %val = call double @llvm.fma.f64(double %nega, double %b, double %c) 61; CHECK: fmsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} 62; CHECK-NOFAST: fmsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} 63 ret double %val 64} 65 66define double @testd_fnmadd(double %a, double %b, double %c) { 67; CHECK-LABEL: testd_fnmadd: 68; CHECK-NOFAST-LABEL: testd_fnmadd: 69 %nega = fsub double -0.0, %a 70 %negc = fsub double -0.0, %c 71 %val = call double @llvm.fma.f64(double %nega, double %b, double %negc) 72; CHECK: fnmadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} 73; CHECK-NOFAST: fnmadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} 74 ret double %val 75} 76 77define double @testd_fnmsub(double %a, double %b, double %c) { 78; CHECK-LABEL: testd_fnmsub: 79; CHECK-NOFAST-LABEL: testd_fnmsub: 80 %negc = fsub double -0.0, %c 81 %val = call double @llvm.fma.f64(double %a, double %b, double %negc) 82; CHECK: fnmsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} 83; CHECK-NOFAST: fnmsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}} 84 ret double %val 85} 86 87define float @test_fmadd_unfused(float %a, float %b, float %c) { 88; CHECK-LABEL: test_fmadd_unfused: 89; CHECK-NOFAST-LABEL: test_fmadd_unfused: 90 %prod = fmul float %b, %c 91 %sum = fadd float %a, %prod 92; CHECK: fmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 93; CHECK-NOFAST-NOT: fmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 94; CHECK-NOFAST: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 95; CHECK-NOFAST: fadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 96 ret float %sum 97} 98 99define float @test_fmsub_unfused(float %a, float %b, float %c) { 100; CHECK-LABEL: test_fmsub_unfused: 101; CHECK-NOFAST-LABEL: test_fmsub_unfused: 102 %prod = fmul float %b, %c 103 %diff = fsub float %a, %prod 104; CHECK: fmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 105; CHECK-NOFAST-NOT: fmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 106; CHECK-NOFAST: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 107; CHECK-NOFAST: fsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 108 ret float %diff 109} 110 111define float @test_fnmadd_unfused(float %a, float %b, float %c) { 112; CHECK-LABEL: test_fnmadd_unfused: 113; CHECK-NOFAST-LABEL: test_fnmadd_unfused: 114 %nega = fsub float -0.0, %a 115 %prod = fmul float %b, %c 116 %diff = fsub float %nega, %prod 117; CHECK: fnmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 118; CHECK-NOFAST-NOT: fnmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 119; CHECK-NOFAST: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 120; CHECK-NOFAST: fsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 121; CHECK-NOFAST: ret 122 ret float %diff 123} 124 125define float @test_fnmsub_unfused(float %a, float %b, float %c) { 126; CHECK-LABEL: test_fnmsub_unfused: 127; CHECK-NOFAST-LABEL: test_fnmsub_unfused: 128 %nega = fsub float -0.0, %a 129 %prod = fmul float %b, %c 130 %sum = fadd float %nega, %prod 131; CHECK: fnmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 132; CHECK-NOFAST-NOT: fnmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 133; CHECK-NOFAST: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 134; CHECK-NOFAST: fsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 135 ret float %sum 136} 137 138; Another set of tests that check for multiply single use 139 140define float @test_fmadd_unfused_su(float %a, float %b, float %c) { 141; CHECK-LABEL: test_fmadd_unfused_su: 142 %prod = fmul float %b, %c 143 %sum = fadd float %a, %prod 144 %res = fadd float %sum, %prod 145; CHECK-NOT: fmadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 146; CHECK: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 147; CHECK: fadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 148; CHECK: fadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 149 ret float %res 150} 151 152define float @test_fmsub_unfused_su(float %a, float %b, float %c) { 153; CHECK-LABEL: test_fmsub_unfused_su: 154 %prod = fmul float %b, %c 155 %diff = fsub float %a, %prod 156 %res = fsub float %diff, %prod 157; CHECK-NOT: fmsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 158; CHECK: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 159; CHECK: fsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 160; CHECK: fsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}} 161 ret float %res 162} 163 164