1; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 \ 2; RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK-SCALAR %s 3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 \ 4; RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK-VECTOR %s 5 6declare double @llvm.experimental.constrained.fma.f64(double %f1, double %f2, double %f3, metadata, metadata) 7 8define double @f1(double %f1, double %f2, double %acc) #0 { 9; CHECK-LABEL: f1: 10; CHECK-SCALAR: madbr %f4, %f0, %f2 11; CHECK-SCALAR: ldr %f0, %f4 12; CHECK-VECTOR: wfmadb %f0, %f0, %f2, %f4 13; CHECK: br %r14 14 %res = call double @llvm.experimental.constrained.fma.f64 ( 15 double %f1, double %f2, double %acc, 16 metadata !"round.dynamic", 17 metadata !"fpexcept.strict") #0 18 ret double %res 19} 20 21define double @f2(double %f1, double *%ptr, double %acc) #0 { 22; CHECK-LABEL: f2: 23; CHECK: madb %f2, %f0, 0(%r2) 24; CHECK: ldr %f0, %f2 25; CHECK: br %r14 26 %f2 = load double, double *%ptr 27 %res = call double @llvm.experimental.constrained.fma.f64 ( 28 double %f1, double %f2, double %acc, 29 metadata !"round.dynamic", 30 metadata !"fpexcept.strict") #0 31 ret double %res 32} 33 34define double @f3(double %f1, double *%base, double %acc) #0 { 35; CHECK-LABEL: f3: 36; CHECK: madb %f2, %f0, 4088(%r2) 37; CHECK: ldr %f0, %f2 38; CHECK: br %r14 39 %ptr = getelementptr double, double *%base, i64 511 40 %f2 = load double, double *%ptr 41 %res = call double @llvm.experimental.constrained.fma.f64 ( 42 double %f1, double %f2, double %acc, 43 metadata !"round.dynamic", 44 metadata !"fpexcept.strict") #0 45 ret double %res 46} 47 48define double @f4(double %f1, double *%base, double %acc) #0 { 49; The important thing here is that we don't generate an out-of-range 50; displacement. Other sequences besides this one would be OK. 51; 52; CHECK-LABEL: f4: 53; CHECK: aghi %r2, 4096 54; CHECK: madb %f2, %f0, 0(%r2) 55; CHECK: ldr %f0, %f2 56; CHECK: br %r14 57 %ptr = getelementptr double, double *%base, i64 512 58 %f2 = load double, double *%ptr 59 %res = call double @llvm.experimental.constrained.fma.f64 ( 60 double %f1, double %f2, double %acc, 61 metadata !"round.dynamic", 62 metadata !"fpexcept.strict") #0 63 ret double %res 64} 65 66define double @f5(double %f1, double *%base, double %acc) #0 { 67; Here too the important thing is that we don't generate an out-of-range 68; displacement. Other sequences besides this one would be OK. 69; 70; CHECK-LABEL: f5: 71; CHECK: aghi %r2, -8 72; CHECK: madb %f2, %f0, 0(%r2) 73; CHECK: ldr %f0, %f2 74; CHECK: br %r14 75 %ptr = getelementptr double, double *%base, i64 -1 76 %f2 = load double, double *%ptr 77 %res = call double @llvm.experimental.constrained.fma.f64 ( 78 double %f1, double %f2, double %acc, 79 metadata !"round.dynamic", 80 metadata !"fpexcept.strict") #0 81 ret double %res 82} 83 84define double @f6(double %f1, double *%base, i64 %index, double %acc) #0 { 85; CHECK-LABEL: f6: 86; CHECK: sllg %r1, %r3, 3 87; CHECK: madb %f2, %f0, 0(%r1,%r2) 88; CHECK: ldr %f0, %f2 89; CHECK: br %r14 90 %ptr = getelementptr double, double *%base, i64 %index 91 %f2 = load double, double *%ptr 92 %res = call double @llvm.experimental.constrained.fma.f64 ( 93 double %f1, double %f2, double %acc, 94 metadata !"round.dynamic", 95 metadata !"fpexcept.strict") #0 96 ret double %res 97} 98 99define double @f7(double %f1, double *%base, i64 %index, double %acc) #0 { 100; CHECK-LABEL: f7: 101; CHECK: sllg %r1, %r3, 3 102; CHECK: madb %f2, %f0, 4088({{%r1,%r2|%r2,%r1}}) 103; CHECK: ldr %f0, %f2 104; CHECK: br %r14 105 %index2 = add i64 %index, 511 106 %ptr = getelementptr double, double *%base, i64 %index2 107 %f2 = load double, double *%ptr 108 %res = call double @llvm.experimental.constrained.fma.f64 ( 109 double %f1, double %f2, double %acc, 110 metadata !"round.dynamic", 111 metadata !"fpexcept.strict") #0 112 ret double %res 113} 114 115define double @f8(double %f1, double *%base, i64 %index, double %acc) #0 { 116; CHECK-LABEL: f8: 117; CHECK: sllg %r1, %r3, 3 118; CHECK: lay %r1, 4096({{%r1,%r2|%r2,%r1}}) 119; CHECK: madb %f2, %f0, 0(%r1) 120; CHECK: ldr %f0, %f2 121; CHECK: br %r14 122 %index2 = add i64 %index, 512 123 %ptr = getelementptr double, double *%base, i64 %index2 124 %f2 = load double, double *%ptr 125 %res = call double @llvm.experimental.constrained.fma.f64 ( 126 double %f1, double %f2, double %acc, 127 metadata !"round.dynamic", 128 metadata !"fpexcept.strict") #0 129 ret double %res 130} 131 132attributes #0 = { strictfp } 133