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