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