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