1; RUN: llc < %s -mtriple=ve | FileCheck %s 2 3;;; Test ‘llvm.fma.*’ intrinsic 4;;; 5;;; Syntax: 6;;; This is an overloaded intrinsic. You can use llvm.fma on any 7;;; floating-point or vector of floating-point type. Not all targets 8;;; support all types however. 9;;; 10;;; declare float @llvm.fma.f32(float %a, float %b, float %c) 11;;; declare double @llvm.fma.f64(double %a, double %b, double %c) 12;;; declare x86_fp80 @llvm.fma.f80(x86_fp80 %a, x86_fp80 %b, x86_fp80 %c) 13;;; declare fp128 @llvm.fma.f128(fp128 %a, fp128 %b, fp128 %c) 14;;; declare ppc_fp128 @llvm.fma.ppcf128(ppc_fp128 %a, ppc_fp128 %b, 15;;; ppc_fp128 %c) 16;;; 17;;; Overview: 18;;; The ‘llvm.fma.*’ intrinsics perform the fused multiply-add operation. 19;;; 20;;; Arguments: 21;;; The arguments and return value are floating-point numbers of the same 22;;; type. 23;;; 24;;; Semantics: 25;;; Return the same value as a corresponding libm ‘fma’ function but without 26;;; trapping or setting errno. 27;;; 28;;; When specified with the fast-math-flag ‘afn’, the result may be 29;;; approximated using a less accurate calculation. 30;;; 31;;; Note: 32;;; We test only float/double/fp128. 33 34; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 35define float @fma_float_var(float noundef %0, float noundef %1, float noundef %2) { 36; CHECK-LABEL: fma_float_var: 37; CHECK: .LBB{{[0-9]+}}_2: 38; CHECK-NEXT: lea %s3, fmaf@lo 39; CHECK-NEXT: and %s3, %s3, (32)0 40; CHECK-NEXT: lea.sl %s12, fmaf@hi(, %s3) 41; CHECK-NEXT: bsic %s10, (, %s12) 42; CHECK-NEXT: or %s11, 0, %s9 43 %4 = tail call fast float @llvm.fma.f32(float %0, float %1, float %2) 44 ret float %4 45} 46 47; Function Attrs: mustprogress nocallback nofree nosync nounwind readnone speculatable willreturn 48declare float @llvm.fma.f32(float, float, float) 49 50; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 51define double @fma_double_var(double noundef %0, double noundef %1, double noundef %2) { 52; CHECK-LABEL: fma_double_var: 53; CHECK: .LBB{{[0-9]+}}_2: 54; CHECK-NEXT: lea %s3, fma@lo 55; CHECK-NEXT: and %s3, %s3, (32)0 56; CHECK-NEXT: lea.sl %s12, fma@hi(, %s3) 57; CHECK-NEXT: bsic %s10, (, %s12) 58; CHECK-NEXT: or %s11, 0, %s9 59 %4 = tail call fast double @llvm.fma.f64(double %0, double %1, double %2) 60 ret double %4 61} 62 63; Function Attrs: mustprogress nocallback nofree nosync nounwind readnone speculatable willreturn 64declare double @llvm.fma.f64(double, double, double) 65 66; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 67define fp128 @fma_quad_var(fp128 noundef %0, fp128 noundef %1, fp128 noundef %2) { 68; CHECK-LABEL: fma_quad_var: 69; CHECK: .LBB{{[0-9]+}}_2: 70; CHECK-NEXT: lea %s6, fmal@lo 71; CHECK-NEXT: and %s6, %s6, (32)0 72; CHECK-NEXT: lea.sl %s12, fmal@hi(, %s6) 73; CHECK-NEXT: bsic %s10, (, %s12) 74; CHECK-NEXT: or %s11, 0, %s9 75 %4 = tail call fast fp128 @llvm.fma.f128(fp128 %0, fp128 %1, fp128 %2) 76 ret fp128 %4 77} 78 79; Function Attrs: mustprogress nocallback nofree nosync nounwind readnone speculatable willreturn 80declare fp128 @llvm.fma.f128(fp128, fp128, fp128) 81 82; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn 83define float @fma_float_fore_zero(float noundef %0, float noundef returned %1) { 84; CHECK-LABEL: fma_float_fore_zero: 85; CHECK: # %bb.0: 86; CHECK-NEXT: or %s0, 0, %s1 87; CHECK-NEXT: b.l.t (, %s10) 88 ret float %1 89} 90 91; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn 92define double @fma_double_fore_zero(double noundef %0, double noundef returned %1) { 93; CHECK-LABEL: fma_double_fore_zero: 94; CHECK: # %bb.0: 95; CHECK-NEXT: or %s0, 0, %s1 96; CHECK-NEXT: b.l.t (, %s10) 97 ret double %1 98} 99 100; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn 101define fp128 @fma_quad_fore_zero(fp128 noundef %0, fp128 noundef returned %1) { 102; CHECK-LABEL: fma_quad_fore_zero: 103; CHECK: # %bb.0: 104; CHECK-NEXT: or %s0, 0, %s2 105; CHECK-NEXT: or %s1, 0, %s3 106; CHECK-NEXT: b.l.t (, %s10) 107 ret fp128 %1 108} 109 110; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn 111define float @fma_float_back_zero(float noundef %0, float noundef returned %1) { 112; CHECK-LABEL: fma_float_back_zero: 113; CHECK: # %bb.0: 114; CHECK-NEXT: or %s0, 0, %s1 115; CHECK-NEXT: b.l.t (, %s10) 116 ret float %1 117} 118 119; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn 120define double @fma_double_back_zero(double noundef %0, double noundef returned %1) { 121; CHECK-LABEL: fma_double_back_zero: 122; CHECK: # %bb.0: 123; CHECK-NEXT: or %s0, 0, %s1 124; CHECK-NEXT: b.l.t (, %s10) 125 ret double %1 126} 127 128; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn 129define fp128 @fma_quad_back_zero(fp128 noundef %0, fp128 noundef returned %1) { 130; CHECK-LABEL: fma_quad_back_zero: 131; CHECK: # %bb.0: 132; CHECK-NEXT: or %s0, 0, %s2 133; CHECK-NEXT: or %s1, 0, %s3 134; CHECK-NEXT: b.l.t (, %s10) 135 ret fp128 %1 136} 137 138; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 139define float @fma_float_fore_const(float noundef %0, float noundef %1) { 140; CHECK-LABEL: fma_float_fore_const: 141; CHECK: .LBB{{[0-9]+}}_2: 142; CHECK-NEXT: or %s2, 0, %s1 143; CHECK-NEXT: lea %s1, fmaf@lo 144; CHECK-NEXT: and %s1, %s1, (32)0 145; CHECK-NEXT: lea.sl %s12, fmaf@hi(, %s1) 146; CHECK-NEXT: lea.sl %s1, -1073741824 147; CHECK-NEXT: bsic %s10, (, %s12) 148; CHECK-NEXT: or %s11, 0, %s9 149 %3 = tail call fast float @llvm.fma.f32(float %0, float -2.000000e+00, float %1) 150 ret float %3 151} 152 153; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 154define double @fma_double_fore_const(double noundef %0, double noundef %1) { 155; CHECK-LABEL: fma_double_fore_const: 156; CHECK: .LBB{{[0-9]+}}_2: 157; CHECK-NEXT: or %s2, 0, %s1 158; CHECK-NEXT: lea %s1, fma@lo 159; CHECK-NEXT: and %s1, %s1, (32)0 160; CHECK-NEXT: lea.sl %s12, fma@hi(, %s1) 161; CHECK-NEXT: lea.sl %s1, -1073741824 162; CHECK-NEXT: bsic %s10, (, %s12) 163; CHECK-NEXT: or %s11, 0, %s9 164 %3 = tail call fast double @llvm.fma.f64(double %0, double -2.000000e+00, double %1) 165 ret double %3 166} 167 168; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 169define fp128 @fma_quad_fore_const(fp128 noundef %0, fp128 noundef %1) { 170; CHECK-LABEL: fma_quad_fore_const: 171; CHECK: .LBB{{[0-9]+}}_2: 172; CHECK-NEXT: or %s4, 0, %s2 173; CHECK-NEXT: or %s5, 0, %s3 174; CHECK-NEXT: lea %s2, .LCPI{{[0-9]+}}_0@lo 175; CHECK-NEXT: and %s2, %s2, (32)0 176; CHECK-NEXT: lea.sl %s6, .LCPI{{[0-9]+}}_0@hi(, %s2) 177; CHECK-NEXT: ld %s2, 8(, %s6) 178; CHECK-NEXT: ld %s3, (, %s6) 179; CHECK-NEXT: lea %s6, fmal@lo 180; CHECK-NEXT: and %s6, %s6, (32)0 181; CHECK-NEXT: lea.sl %s12, fmal@hi(, %s6) 182; CHECK-NEXT: bsic %s10, (, %s12) 183; CHECK-NEXT: or %s11, 0, %s9 184 %3 = tail call fast fp128 @llvm.fma.f128(fp128 %0, fp128 0xL0000000000000000C000000000000000, fp128 %1) 185 ret fp128 %3 186} 187 188; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 189define float @fma_float_back_const(float noundef %0, float noundef %1) { 190; CHECK-LABEL: fma_float_back_const: 191; CHECK: .LBB{{[0-9]+}}_2: 192; CHECK-NEXT: or %s2, 0, %s1 193; CHECK-NEXT: lea %s1, fmaf@lo 194; CHECK-NEXT: and %s1, %s1, (32)0 195; CHECK-NEXT: lea.sl %s12, fmaf@hi(, %s1) 196; CHECK-NEXT: lea.sl %s1, -1073741824 197; CHECK-NEXT: bsic %s10, (, %s12) 198; CHECK-NEXT: or %s11, 0, %s9 199 %3 = tail call fast float @llvm.fma.f32(float %0, float -2.000000e+00, float %1) 200 ret float %3 201} 202 203; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 204define double @fma_double_back_const(double noundef %0, double noundef %1) { 205; CHECK-LABEL: fma_double_back_const: 206; CHECK: .LBB{{[0-9]+}}_2: 207; CHECK-NEXT: or %s2, 0, %s1 208; CHECK-NEXT: lea %s1, fma@lo 209; CHECK-NEXT: and %s1, %s1, (32)0 210; CHECK-NEXT: lea.sl %s12, fma@hi(, %s1) 211; CHECK-NEXT: lea.sl %s1, -1073741824 212; CHECK-NEXT: bsic %s10, (, %s12) 213; CHECK-NEXT: or %s11, 0, %s9 214 %3 = tail call fast double @llvm.fma.f64(double %0, double -2.000000e+00, double %1) 215 ret double %3 216} 217 218; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 219define fp128 @fma_quad_back_const(fp128 noundef %0, fp128 noundef %1) { 220; CHECK-LABEL: fma_quad_back_const: 221; CHECK: .LBB{{[0-9]+}}_2: 222; CHECK-NEXT: or %s4, 0, %s2 223; CHECK-NEXT: or %s5, 0, %s3 224; CHECK-NEXT: lea %s2, .LCPI{{[0-9]+}}_0@lo 225; CHECK-NEXT: and %s2, %s2, (32)0 226; CHECK-NEXT: lea.sl %s6, .LCPI{{[0-9]+}}_0@hi(, %s2) 227; CHECK-NEXT: ld %s2, 8(, %s6) 228; CHECK-NEXT: ld %s3, (, %s6) 229; CHECK-NEXT: lea %s6, fmal@lo 230; CHECK-NEXT: and %s6, %s6, (32)0 231; CHECK-NEXT: lea.sl %s12, fmal@hi(, %s6) 232; CHECK-NEXT: bsic %s10, (, %s12) 233; CHECK-NEXT: or %s11, 0, %s9 234 %3 = tail call fast fp128 @llvm.fma.f128(fp128 %0, fp128 0xL0000000000000000C000000000000000, fp128 %1) 235 ret fp128 %3 236} 237