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 6 declare double @llvm.fma.f64(double %f1, double %f2, double %f3) 7 8 define double @f1(double %f1, double %f2, double %acc) { 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.fma.f64 (double %f1, double %f2, double %acc) 15 ret double %res 16 } 17 18 define double @f2(double %f1, double *%ptr, double %acc) { 19 ; CHECK-LABEL: f2: 20 ; CHECK: madb %f2, %f0, 0(%r2) 21 ; CHECK: ldr %f0, %f2 22 ; CHECK: br %r14 23 %f2 = load double , double *%ptr 24 %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc) 25 ret double %res 26 } 27 28 define double @f3(double %f1, double *%base, double %acc) { 29 ; CHECK-LABEL: f3: 30 ; CHECK: madb %f2, %f0, 4088(%r2) 31 ; CHECK: ldr %f0, %f2 32 ; CHECK: br %r14 33 %ptr = getelementptr double, double *%base, i64 511 34 %f2 = load double , double *%ptr 35 %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc) 36 ret double %res 37 } 38 39 define double @f4(double %f1, double *%base, double %acc) { 40 ; The important thing here is that we don't generate an out-of-range 41 ; displacement. Other sequences besides this one would be OK. 42 ; 43 ; CHECK-LABEL: f4: 44 ; CHECK: aghi %r2, 4096 45 ; CHECK: madb %f2, %f0, 0(%r2) 46 ; CHECK: ldr %f0, %f2 47 ; CHECK: br %r14 48 %ptr = getelementptr double, double *%base, i64 512 49 %f2 = load double , double *%ptr 50 %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc) 51 ret double %res 52 } 53 54 define double @f5(double %f1, double *%base, double %acc) { 55 ; Here too the important thing is that we don't generate an out-of-range 56 ; displacement. Other sequences besides this one would be OK. 57 ; 58 ; CHECK-LABEL: f5: 59 ; CHECK: aghi %r2, -8 60 ; CHECK: madb %f2, %f0, 0(%r2) 61 ; CHECK: ldr %f0, %f2 62 ; CHECK: br %r14 63 %ptr = getelementptr double, double *%base, i64 -1 64 %f2 = load double , double *%ptr 65 %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc) 66 ret double %res 67 } 68 69 define double @f6(double %f1, double *%base, i64 %index, double %acc) { 70 ; CHECK-LABEL: f6: 71 ; CHECK: sllg %r1, %r3, 3 72 ; CHECK: madb %f2, %f0, 0(%r1,%r2) 73 ; CHECK: ldr %f0, %f2 74 ; CHECK: br %r14 75 %ptr = getelementptr double, double *%base, i64 %index 76 %f2 = load double , double *%ptr 77 %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc) 78 ret double %res 79 } 80 81 define double @f7(double %f1, double *%base, i64 %index, double %acc) { 82 ; CHECK-LABEL: f7: 83 ; CHECK: sllg %r1, %r3, 3 84 ; CHECK: madb %f2, %f0, 4088({{%r1,%r2|%r2,%r1}}) 85 ; CHECK: ldr %f0, %f2 86 ; CHECK: br %r14 87 %index2 = add i64 %index, 511 88 %ptr = getelementptr double, double *%base, i64 %index2 89 %f2 = load double , double *%ptr 90 %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc) 91 ret double %res 92 } 93 94 define double @f8(double %f1, double *%base, i64 %index, double %acc) { 95 ; CHECK-LABEL: f8: 96 ; CHECK: sllg %r1, %r3, 3 97 ; CHECK: lay %r1, 4096({{%r1,%r2|%r2,%r1}}) 98 ; CHECK: madb %f2, %f0, 0(%r1) 99 ; CHECK: ldr %f0, %f2 100 ; CHECK: br %r14 101 %index2 = add i64 %index, 512 102 %ptr = getelementptr double, double *%base, i64 %index2 103 %f2 = load double , double *%ptr 104 %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc) 105 ret double %res 106 } 107