[clang] [llvm] [SystemZ] Add support for half (fp16) (PR #109164)
Matt Arsenault via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 7 00:16:36 PDT 2024
================
@@ -0,0 +1,201 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z16 | FileCheck %s
+;
+; Tests for 16-bit floating point (half).
+
+; Incoming half arguments added together and returned.
+define half @fun0(half %Op0, half %Op1) {
+; CHECK-LABEL: fun0:
+; CHECK: # %bb.0: # %entry
+; 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, -168
+; CHECK-NEXT: .cfi_def_cfa_offset 328
+; CHECK-NEXT: std %f8, 160(%r15) # 8-byte Folded Spill
+; CHECK-NEXT: .cfi_offset %f8, -168
+; CHECK-NEXT: vlgvf %r0, %v2, 0
+; CHECK-NEXT: llghr %r2, %r0
+; CHECK-NEXT: vlgvf %r13, %v0, 0
+; CHECK-NEXT: brasl %r14, __gnu_h2f_ieee at PLT
+; CHECK-NEXT: llghr %r2, %r13
+; CHECK-NEXT: ldr %f8, %f0
+; CHECK-NEXT: brasl %r14, __gnu_h2f_ieee at PLT
+; CHECK-NEXT: aebr %f0, %f8
+; CHECK-NEXT: brasl %r14, __gnu_f2h_ieee at PLT
+; CHECK-NEXT: ld %f8, 160(%r15) # 8-byte Folded Reload
+; CHECK-NEXT: vlvgf %v0, %r2, 0
+; CHECK-NEXT: lmg %r13, %r15, 272(%r15)
+; CHECK-NEXT: br %r14
+entry:
+ %Res = fadd half %Op0, %Op1
+ ret half %Res
+}
+
+; The half values are loaded and stored instead.
+define void @fun1(ptr %Op0, ptr %Op1, ptr %Dst) {
+; CHECK-LABEL: fun1:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: stmg %r12, %r15, 96(%r15)
+; CHECK-NEXT: .cfi_offset %r12, -64
+; CHECK-NEXT: .cfi_offset %r13, -56
+; CHECK-NEXT: .cfi_offset %r14, -48
+; CHECK-NEXT: .cfi_offset %r15, -40
+; CHECK-NEXT: aghi %r15, -168
+; CHECK-NEXT: .cfi_def_cfa_offset 328
+; CHECK-NEXT: std %f8, 160(%r15) # 8-byte Folded Spill
+; CHECK-NEXT: .cfi_offset %f8, -168
+; CHECK-NEXT: llgh %r12, 0(%r2)
+; CHECK-NEXT: llgh %r2, 0(%r3)
+; CHECK-NEXT: lgr %r13, %r4
+; CHECK-NEXT: brasl %r14, __gnu_h2f_ieee at PLT
+; CHECK-NEXT: lgr %r2, %r12
+; CHECK-NEXT: ldr %f8, %f0
+; CHECK-NEXT: brasl %r14, __gnu_h2f_ieee at PLT
+; CHECK-NEXT: aebr %f0, %f8
+; CHECK-NEXT: brasl %r14, __gnu_f2h_ieee at PLT
+; CHECK-NEXT: ld %f8, 160(%r15) # 8-byte Folded Reload
+; CHECK-NEXT: sth %r2, 0(%r13)
+; CHECK-NEXT: lmg %r12, %r15, 264(%r15)
+; CHECK-NEXT: br %r14
+entry:
+ %0 = load half, ptr %Op0, align 2
+ %1 = load half, ptr %Op1, align 2
+ %add = fadd half %0, %1
+ store half %add, ptr %Dst, align 2
+ ret void
+}
+
+; Test a chain of half operations which should have each operation surrounded
+; by conversions to/from fp32 for proper emulation.
+define half @fun2(half %Op0, half %Op1, half %Op2) {
+; CHECK-LABEL: fun2:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: stmg %r12, %r15, 96(%r15)
+; CHECK-NEXT: .cfi_offset %r12, -64
+; CHECK-NEXT: .cfi_offset %r13, -56
+; CHECK-NEXT: .cfi_offset %r14, -48
+; CHECK-NEXT: .cfi_offset %r15, -40
+; CHECK-NEXT: aghi %r15, -168
+; CHECK-NEXT: .cfi_def_cfa_offset 328
+; CHECK-NEXT: std %f8, 160(%r15) # 8-byte Folded Spill
+; CHECK-NEXT: .cfi_offset %f8, -168
+; CHECK-NEXT: vlgvf %r0, %v2, 0
+; CHECK-NEXT: llghr %r2, %r0
+; CHECK-NEXT: vlgvf %r13, %v4, 0
+; CHECK-NEXT: vlgvf %r12, %v0, 0
+; CHECK-NEXT: brasl %r14, __gnu_h2f_ieee at PLT
+; CHECK-NEXT: llghr %r2, %r12
+; CHECK-NEXT: ldr %f8, %f0
+; CHECK-NEXT: brasl %r14, __gnu_h2f_ieee at PLT
+; CHECK-NEXT: aebr %f0, %f8
+; CHECK-NEXT: brasl %r14, __gnu_f2h_ieee at PLT
+; CHECK-NEXT: llghr %r2, %r2
+; CHECK-NEXT: brasl %r14, __gnu_h2f_ieee at PLT
+; CHECK-NEXT: llghr %r2, %r13
+; CHECK-NEXT: ldr %f8, %f0
+; CHECK-NEXT: brasl %r14, __gnu_h2f_ieee at PLT
+; CHECK-NEXT: wfasb %f0, %f8, %f0
+; CHECK-NEXT: brasl %r14, __gnu_f2h_ieee at PLT
+; CHECK-NEXT: ld %f8, 160(%r15) # 8-byte Folded Reload
+; CHECK-NEXT: vlvgf %v0, %r2, 0
+; CHECK-NEXT: lmg %r12, %r15, 264(%r15)
+; CHECK-NEXT: br %r14
+entry:
+ %A0 = fadd half %Op0, %Op1
+ %Res = fadd half %A0, %Op2
+ ret half %Res
+}
+
+; Store an incoming half argument and return a loaded one.
+define half @fun3(half %Op0, ptr %Dst, ptr %Src) {
+; CHECK-LABEL: fun3:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vlgvf %r0, %v0, 0
+; CHECK-NEXT: sth %r0, 0(%r2)
+; CHECK-NEXT: lh %r0, 0(%r3)
+; CHECK-NEXT: vlvgf %v0, %r0, 0
+; CHECK-NEXT: br %r14
+entry:
+ store half %Op0, ptr %Dst
+
+ %Res = load half, ptr %Src
+ ret half %Res
+}
+
+; Call a function with half argument and return values.
+declare half @foo(half)
+define void @fun4(ptr %Src, ptr %Dst) {
+; CHECK-LABEL: fun4:
+; CHECK: # %bb.0: # %entry
+; 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: lh %r0, 0(%r2)
+; CHECK-NEXT: vlvgf %v0, %r0, 0
+; CHECK-NEXT: lgr %r13, %r3
+; CHECK-NEXT: brasl %r14, foo at PLT
+; CHECK-NEXT: vlgvf %r0, %v0, 0
+; CHECK-NEXT: sth %r0, 0(%r13)
+; CHECK-NEXT: lmg %r13, %r15, 264(%r15)
+; CHECK-NEXT: br %r14
+entry:
+ %arg = load half, ptr %Src
+ %Res = call half @foo(half %arg)
+ store half %Res, ptr %Dst
+ ret void
+}
----------------
arsenm wrote:
Test a tail call too
https://github.com/llvm/llvm-project/pull/109164
More information about the cfe-commits
mailing list