| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 |
| ; Test that library calls are emitted for LLVM IR intrinsics |
| ; |
| ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s |
| |
| define half @f1(half %x, i16 %y) nounwind { |
| ; CHECK-LABEL: f1: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: stmg %r13, %r15, 104(%r15) |
| ; CHECK-NEXT: aghi %r15, -160 |
| ; CHECK-NEXT: lhr %r13, %r2 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: llgfr %r2, %r13 |
| ; CHECK-NEXT: brasl %r14, __powisf2@PLT |
| ; CHECK-NEXT: brasl %r14, __truncsfhf2@PLT |
| ; CHECK-NEXT: lmg %r13, %r15, 264(%r15) |
| ; CHECK-NEXT: br %r14 |
| %tmp = call half @llvm.powi.f16.i16(half %x, i16 %y) |
| ret half %tmp |
| } |
| |
| define half @f2(half %x, half %y) nounwind { |
| ; CHECK-LABEL: f2: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: stmg %r14, %r15, 112(%r15) |
| ; CHECK-NEXT: aghi %r15, -176 |
| ; CHECK-NEXT: std %f8, 168(%r15) # 8-byte Spill |
| ; CHECK-NEXT: std %f9, 160(%r15) # 8-byte Spill |
| ; CHECK-NEXT: ler %f8, %f2 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: ler %f9, %f0 |
| ; CHECK-NEXT: ler %f0, %f8 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: ler %f2, %f0 |
| ; CHECK-NEXT: ler %f0, %f9 |
| ; CHECK-NEXT: brasl %r14, powf@PLT |
| ; CHECK-NEXT: brasl %r14, __truncsfhf2@PLT |
| ; CHECK-NEXT: ld %f8, 168(%r15) # 8-byte Reload |
| ; CHECK-NEXT: ld %f9, 160(%r15) # 8-byte Reload |
| ; CHECK-NEXT: lmg %r14, %r15, 288(%r15) |
| ; CHECK-NEXT: br %r14 |
| %tmp = call half @llvm.pow.f16(half %x, half %y) |
| ret half %tmp |
| } |
| |
| define half @f3(half %x) nounwind { |
| ; CHECK-LABEL: f3: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: stmg %r14, %r15, 112(%r15) |
| ; CHECK-NEXT: aghi %r15, -160 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: brasl %r14, sinf@PLT |
| ; CHECK-NEXT: brasl %r14, __truncsfhf2@PLT |
| ; CHECK-NEXT: lmg %r14, %r15, 272(%r15) |
| ; CHECK-NEXT: br %r14 |
| %tmp = call half @llvm.sin.f16(half %x) |
| ret half %tmp |
| } |
| |
| define half @f4(half %x) nounwind { |
| ; CHECK-LABEL: f4: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: stmg %r14, %r15, 112(%r15) |
| ; CHECK-NEXT: aghi %r15, -160 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: brasl %r14, cosf@PLT |
| ; CHECK-NEXT: brasl %r14, __truncsfhf2@PLT |
| ; CHECK-NEXT: lmg %r14, %r15, 272(%r15) |
| ; CHECK-NEXT: br %r14 |
| %tmp = call half @llvm.cos.f16(half %x) |
| ret half %tmp |
| } |
| |
| define half @f5(half %x) nounwind { |
| ; CHECK-LABEL: f5: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: stmg %r14, %r15, 112(%r15) |
| ; CHECK-NEXT: aghi %r15, -160 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: brasl %r14, expf@PLT |
| ; CHECK-NEXT: brasl %r14, __truncsfhf2@PLT |
| ; CHECK-NEXT: lmg %r14, %r15, 272(%r15) |
| ; CHECK-NEXT: br %r14 |
| %tmp = call half @llvm.exp.f16(half %x) |
| ret half %tmp |
| } |
| |
| define half @f6(half %x) nounwind { |
| ; CHECK-LABEL: f6: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: stmg %r14, %r15, 112(%r15) |
| ; CHECK-NEXT: aghi %r15, -160 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: brasl %r14, exp2f@PLT |
| ; CHECK-NEXT: brasl %r14, __truncsfhf2@PLT |
| ; CHECK-NEXT: lmg %r14, %r15, 272(%r15) |
| ; CHECK-NEXT: br %r14 |
| %tmp = call half @llvm.exp2.f16(half %x) |
| ret half %tmp |
| } |
| |
| define half @f7(half %x) nounwind { |
| ; CHECK-LABEL: f7: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: stmg %r14, %r15, 112(%r15) |
| ; CHECK-NEXT: aghi %r15, -160 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: brasl %r14, logf@PLT |
| ; CHECK-NEXT: brasl %r14, __truncsfhf2@PLT |
| ; CHECK-NEXT: lmg %r14, %r15, 272(%r15) |
| ; CHECK-NEXT: br %r14 |
| %tmp = call half @llvm.log.f16(half %x) |
| ret half %tmp |
| } |
| |
| define half @f8(half %x) nounwind { |
| ; CHECK-LABEL: f8: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: stmg %r14, %r15, 112(%r15) |
| ; CHECK-NEXT: aghi %r15, -160 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: brasl %r14, log2f@PLT |
| ; CHECK-NEXT: brasl %r14, __truncsfhf2@PLT |
| ; CHECK-NEXT: lmg %r14, %r15, 272(%r15) |
| ; CHECK-NEXT: br %r14 |
| %tmp = call half @llvm.log2.f16(half %x) |
| ret half %tmp |
| } |
| |
| define half @f9(half %x) nounwind { |
| ; CHECK-LABEL: f9: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: stmg %r14, %r15, 112(%r15) |
| ; CHECK-NEXT: aghi %r15, -160 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: brasl %r14, log10f@PLT |
| ; CHECK-NEXT: brasl %r14, __truncsfhf2@PLT |
| ; CHECK-NEXT: lmg %r14, %r15, 272(%r15) |
| ; CHECK-NEXT: br %r14 |
| %tmp = call half @llvm.log10.f16(half %x) |
| ret half %tmp |
| } |
| |
| define half @f10(half %x, half %y) nounwind { |
| ; CHECK-LABEL: f10: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: stmg %r14, %r15, 112(%r15) |
| ; CHECK-NEXT: aghi %r15, -176 |
| ; CHECK-NEXT: std %f8, 168(%r15) # 8-byte Spill |
| ; CHECK-NEXT: std %f9, 160(%r15) # 8-byte Spill |
| ; CHECK-NEXT: ler %f8, %f2 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: ler %f9, %f0 |
| ; CHECK-NEXT: ler %f0, %f8 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: ler %f2, %f0 |
| ; CHECK-NEXT: ler %f0, %f9 |
| ; CHECK-NEXT: brasl %r14, fminf@PLT |
| ; CHECK-NEXT: brasl %r14, __truncsfhf2@PLT |
| ; CHECK-NEXT: ld %f8, 168(%r15) # 8-byte Reload |
| ; CHECK-NEXT: ld %f9, 160(%r15) # 8-byte Reload |
| ; CHECK-NEXT: lmg %r14, %r15, 288(%r15) |
| ; CHECK-NEXT: br %r14 |
| %tmp = call half @llvm.minnum.f16(half %x, half %y) |
| ret half %tmp |
| } |
| |
| define half @f11(half %x, half %y) nounwind { |
| ; CHECK-LABEL: f11: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: stmg %r14, %r15, 112(%r15) |
| ; CHECK-NEXT: aghi %r15, -176 |
| ; CHECK-NEXT: std %f8, 168(%r15) # 8-byte Spill |
| ; CHECK-NEXT: std %f9, 160(%r15) # 8-byte Spill |
| ; CHECK-NEXT: ler %f8, %f2 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: ler %f9, %f0 |
| ; CHECK-NEXT: ler %f0, %f8 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: ler %f2, %f0 |
| ; CHECK-NEXT: ler %f0, %f9 |
| ; CHECK-NEXT: brasl %r14, fmaxf@PLT |
| ; CHECK-NEXT: brasl %r14, __truncsfhf2@PLT |
| ; CHECK-NEXT: ld %f8, 168(%r15) # 8-byte Reload |
| ; CHECK-NEXT: ld %f9, 160(%r15) # 8-byte Reload |
| ; CHECK-NEXT: lmg %r14, %r15, 288(%r15) |
| ; CHECK-NEXT: br %r14 |
| %tmp = call half @llvm.maxnum.f16(half %x, half %y) |
| ret half %tmp |
| } |
| |
| ; Verify that "nnan" minnum/maxnum calls are transformed to |
| ; compare+select sequences instead of libcalls. |
| define half @f12(half %x, half %y) nounwind { |
| ; CHECK-LABEL: f12: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: stmg %r14, %r15, 112(%r15) |
| ; CHECK-NEXT: aghi %r15, -176 |
| ; CHECK-NEXT: std %f8, 168(%r15) # 8-byte Spill |
| ; CHECK-NEXT: std %f9, 160(%r15) # 8-byte Spill |
| ; CHECK-NEXT: ler %f9, %f0 |
| ; CHECK-NEXT: ler %f0, %f2 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: ler %f8, %f0 |
| ; CHECK-NEXT: ler %f0, %f9 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: cebr %f0, %f8 |
| ; CHECK-NEXT: jl .LBB11_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: ler %f0, %f8 |
| ; CHECK-NEXT: .LBB11_2: |
| ; CHECK-NEXT: brasl %r14, __truncsfhf2@PLT |
| ; CHECK-NEXT: ld %f8, 168(%r15) # 8-byte Reload |
| ; CHECK-NEXT: ld %f9, 160(%r15) # 8-byte Reload |
| ; CHECK-NEXT: lmg %r14, %r15, 288(%r15) |
| ; CHECK-NEXT: br %r14 |
| %tmp = call nnan half @llvm.minnum.f16(half %x, half %y) |
| ret half %tmp |
| } |
| |
| define half @f13(half %x, half %y) nounwind { |
| ; CHECK-LABEL: f13: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: stmg %r14, %r15, 112(%r15) |
| ; CHECK-NEXT: aghi %r15, -176 |
| ; CHECK-NEXT: std %f8, 168(%r15) # 8-byte Spill |
| ; CHECK-NEXT: std %f9, 160(%r15) # 8-byte Spill |
| ; CHECK-NEXT: ler %f9, %f0 |
| ; CHECK-NEXT: ler %f0, %f2 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: ler %f8, %f0 |
| ; CHECK-NEXT: ler %f0, %f9 |
| ; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT |
| ; CHECK-NEXT: cebr %f0, %f8 |
| ; CHECK-NEXT: jh .LBB12_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: ler %f0, %f8 |
| ; CHECK-NEXT: .LBB12_2: |
| ; CHECK-NEXT: brasl %r14, __truncsfhf2@PLT |
| ; CHECK-NEXT: ld %f8, 168(%r15) # 8-byte Reload |
| ; CHECK-NEXT: ld %f9, 160(%r15) # 8-byte Reload |
| ; CHECK-NEXT: lmg %r14, %r15, 288(%r15) |
| ; CHECK-NEXT: br %r14 |
| %tmp = call nnan half @llvm.maxnum.f16(half %x, half %y) |
| ret half %tmp |
| } |
| |
| declare half @llvm.powi.f16.i16(half, i16) |
| declare half @llvm.pow.f16(half, half) |
| |
| declare half @llvm.sin.f16(half) |
| declare half @llvm.cos.f16(half) |
| |
| declare half @llvm.exp.f16(half) |
| declare half @llvm.exp2.f16(half) |
| |
| declare half @llvm.log.f16(half) |
| declare half @llvm.log2.f16(half) |
| declare half @llvm.log10.f16(half) |
| |
| declare half @llvm.minnum.f16(half, half) |
| declare half @llvm.maxnum.f16(half, half) |