- _Float16 is now accepted by Clang. - The half IR type is fully handled by the backend. - These values are passed in FP registers and converted to/from float around each operation. - Compiler-rt conversion functions are now built for s390x including the missing extendhfdf2 which was added. Fixes #50374
313 lines
10 KiB
LLVM
313 lines
10 KiB
LLVM
; 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) {
|
|
; CHECK-LABEL: f1:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r13, %r15, 104(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r13, -56
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -160
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 320
|
|
; 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) {
|
|
; CHECK-LABEL: f2:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -176
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 336
|
|
; CHECK-NEXT: std %f8, 168(%r15) # 8-byte Spill
|
|
; CHECK-NEXT: std %f9, 160(%r15) # 8-byte Spill
|
|
; CHECK-NEXT: .cfi_offset %f8, -168
|
|
; CHECK-NEXT: .cfi_offset %f9, -176
|
|
; 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) {
|
|
; CHECK-LABEL: f3:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -160
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 320
|
|
; 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) {
|
|
; CHECK-LABEL: f4:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -160
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 320
|
|
; 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) {
|
|
; CHECK-LABEL: f5:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -160
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 320
|
|
; 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) {
|
|
; CHECK-LABEL: f6:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -160
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 320
|
|
; 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) {
|
|
; CHECK-LABEL: f7:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -160
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 320
|
|
; 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) {
|
|
; CHECK-LABEL: f8:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -160
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 320
|
|
; 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) {
|
|
; CHECK-LABEL: f9:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -160
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 320
|
|
; 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) {
|
|
; CHECK-LABEL: f10:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -176
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 336
|
|
; CHECK-NEXT: std %f8, 168(%r15) # 8-byte Spill
|
|
; CHECK-NEXT: std %f9, 160(%r15) # 8-byte Spill
|
|
; CHECK-NEXT: .cfi_offset %f8, -168
|
|
; CHECK-NEXT: .cfi_offset %f9, -176
|
|
; 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) {
|
|
; CHECK-LABEL: f11:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -176
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 336
|
|
; CHECK-NEXT: std %f8, 168(%r15) # 8-byte Spill
|
|
; CHECK-NEXT: std %f9, 160(%r15) # 8-byte Spill
|
|
; CHECK-NEXT: .cfi_offset %f8, -168
|
|
; CHECK-NEXT: .cfi_offset %f9, -176
|
|
; 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) {
|
|
; CHECK-LABEL: f12:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -176
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 336
|
|
; CHECK-NEXT: std %f8, 168(%r15) # 8-byte Spill
|
|
; CHECK-NEXT: std %f9, 160(%r15) # 8-byte Spill
|
|
; CHECK-NEXT: .cfi_offset %f8, -168
|
|
; CHECK-NEXT: .cfi_offset %f9, -176
|
|
; 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) {
|
|
; CHECK-LABEL: f13:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -176
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 336
|
|
; CHECK-NEXT: std %f8, 168(%r15) # 8-byte Spill
|
|
; CHECK-NEXT: std %f9, 160(%r15) # 8-byte Spill
|
|
; CHECK-NEXT: .cfi_offset %f8, -168
|
|
; CHECK-NEXT: .cfi_offset %f9, -176
|
|
; 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)
|