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.fma.f64(double %f1, double %f2, double %f3) 7 8define 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 18define 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 28define 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 39define 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 54define 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 69define 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 81define 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 94define 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