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 4 declare float @llvm.fma.f32(float, float, float) 5 declare double @llvm.fma.f64(double, double, double) 6 7 define 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 16 define 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 26 define 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 37 define 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 47 define 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 56 define 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 66 define 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 77 define 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 87 define 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 99 define 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 111 define 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 125 define 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 140 define 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 152 define 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