-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[SPARC] Change half
to use soft promotion rather than PromoteFloat
#152727
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-backend-sparc Author: Trevor Gross (tgross35) Changes
The SPARC ABI does not specify a Fixes the SPARC portion of 1. Patch is 50.77 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/152727.diff 4 Files Affected:
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.h b/llvm/lib/Target/Sparc/SparcISelLowering.h
index 0d220f8c3d32e..3a6aaf929707d 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.h
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.h
@@ -28,6 +28,8 @@ namespace llvm {
bool useSoftFloat() const override;
+ bool softPromoteHalfType() const override { return true; }
+
/// computeKnownBitsForTargetNode - Determine which of the bits specified
/// in Mask are known to be either zero or one and return them in the
/// KnownZero/KnownOne bitsets.
diff --git a/llvm/test/CodeGen/SPARC/fp16-promote.ll b/llvm/test/CodeGen/SPARC/fp16-promote.ll
index efe67b04e8fb3..64873b744de50 100644
--- a/llvm/test/CodeGen/SPARC/fp16-promote.ll
+++ b/llvm/test/CodeGen/SPARC/fp16-promote.ll
@@ -329,13 +329,14 @@ define void @test_fadd(ptr %p, ptr %q) nounwind {
; V8-OPT-LABEL: test_fadd:
; V8-OPT: ! %bb.0:
; V8-OPT-NEXT: save %sp, -104, %sp
+; V8-OPT-NEXT: lduh [%i0], %i2
; V8-OPT-NEXT: call __extendhfsf2
-; V8-OPT-NEXT: lduh [%i0], %o0
+; V8-OPT-NEXT: lduh [%i1], %o0
; V8-OPT-NEXT: st %f0, [%fp+-8] ! 4-byte Folded Spill
; V8-OPT-NEXT: call __extendhfsf2
-; V8-OPT-NEXT: lduh [%i1], %o0
+; V8-OPT-NEXT: mov %i2, %o0
; V8-OPT-NEXT: ld [%fp+-8], %f1 ! 4-byte Folded Reload
-; V8-OPT-NEXT: fadds %f1, %f0, %f0
+; V8-OPT-NEXT: fadds %f0, %f1, %f0
; V8-OPT-NEXT: st %f0, [%fp+-4]
; V8-OPT-NEXT: call __truncsfhf2
; V8-OPT-NEXT: ld [%fp+-4], %o0
@@ -346,13 +347,14 @@ define void @test_fadd(ptr %p, ptr %q) nounwind {
; V8-UNOPT-LABEL: test_fadd:
; V8-UNOPT: ! %bb.0:
; V8-UNOPT-NEXT: save %sp, -104, %sp
-; V8-UNOPT-NEXT: call __extendhfsf2
-; V8-UNOPT-NEXT: lduh [%i0], %o0
-; V8-UNOPT-NEXT: st %f0, [%fp+-8] ! 4-byte Folded Spill
+; V8-UNOPT-NEXT: lduh [%i0], %i2
+; V8-UNOPT-NEXT: st %i2, [%fp+-12] ! 4-byte Folded Spill
; V8-UNOPT-NEXT: call __extendhfsf2
; V8-UNOPT-NEXT: lduh [%i1], %o0
-; V8-UNOPT-NEXT: fmovs %f0, %f1
-; V8-UNOPT-NEXT: ld [%fp+-8], %f0 ! 4-byte Folded Reload
+; V8-UNOPT-NEXT: ld [%fp+-12], %o0 ! 4-byte Folded Reload
+; V8-UNOPT-NEXT: call __extendhfsf2
+; V8-UNOPT-NEXT: st %f0, [%fp+-8]
+; V8-UNOPT-NEXT: ld [%fp+-8], %f1 ! 4-byte Folded Reload
; V8-UNOPT-NEXT: fadds %f0, %f1, %f0
; V8-UNOPT-NEXT: st %f0, [%fp+-4]
; V8-UNOPT-NEXT: call __truncsfhf2
@@ -364,13 +366,14 @@ define void @test_fadd(ptr %p, ptr %q) nounwind {
; V9-LABEL: test_fadd:
; V9: ! %bb.0:
; V9-NEXT: save %sp, -104, %sp
+; V9-NEXT: lduh [%i0], %i2
; V9-NEXT: call __extendhfsf2
-; V9-NEXT: lduh [%i0], %o0
+; V9-NEXT: lduh [%i1], %o0
; V9-NEXT: st %f0, [%fp+-8] ! 4-byte Folded Spill
; V9-NEXT: call __extendhfsf2
-; V9-NEXT: lduh [%i1], %o0
+; V9-NEXT: mov %i2, %o0
; V9-NEXT: ld [%fp+-8], %f1 ! 4-byte Folded Reload
-; V9-NEXT: fadds %f1, %f0, %f0
+; V9-NEXT: fadds %f0, %f1, %f0
; V9-NEXT: st %f0, [%fp+-4]
; V9-NEXT: call __truncsfhf2
; V9-NEXT: ld [%fp+-4], %o0
@@ -381,14 +384,15 @@ define void @test_fadd(ptr %p, ptr %q) nounwind {
; SPARC64-LABEL: test_fadd:
; SPARC64: ! %bb.0:
; SPARC64-NEXT: save %sp, -192, %sp
+; SPARC64-NEXT: lduh [%i0], %i2
; SPARC64-NEXT: call __extendhfsf2
-; SPARC64-NEXT: lduh [%i0], %o0
+; SPARC64-NEXT: lduh [%i1], %o0
; SPARC64-NEXT: st %f0, [%fp+2043] ! 4-byte Folded Spill
; SPARC64-NEXT: call __extendhfsf2
-; SPARC64-NEXT: lduh [%i1], %o0
+; SPARC64-NEXT: mov %i2, %o0
; SPARC64-NEXT: ld [%fp+2043], %f1 ! 4-byte Folded Reload
; SPARC64-NEXT: call __truncsfhf2
-; SPARC64-NEXT: fadds %f1, %f0, %f1
+; SPARC64-NEXT: fadds %f0, %f1, %f1
; SPARC64-NEXT: sth %o0, [%i0]
; SPARC64-NEXT: ret
; SPARC64-NEXT: restore
@@ -403,13 +407,14 @@ define void @test_fmul(ptr %p, ptr %q) nounwind {
; V8-OPT-LABEL: test_fmul:
; V8-OPT: ! %bb.0:
; V8-OPT-NEXT: save %sp, -104, %sp
+; V8-OPT-NEXT: lduh [%i0], %i2
; V8-OPT-NEXT: call __extendhfsf2
-; V8-OPT-NEXT: lduh [%i0], %o0
+; V8-OPT-NEXT: lduh [%i1], %o0
; V8-OPT-NEXT: st %f0, [%fp+-8] ! 4-byte Folded Spill
; V8-OPT-NEXT: call __extendhfsf2
-; V8-OPT-NEXT: lduh [%i1], %o0
+; V8-OPT-NEXT: mov %i2, %o0
; V8-OPT-NEXT: ld [%fp+-8], %f1 ! 4-byte Folded Reload
-; V8-OPT-NEXT: fmuls %f1, %f0, %f0
+; V8-OPT-NEXT: fmuls %f0, %f1, %f0
; V8-OPT-NEXT: st %f0, [%fp+-4]
; V8-OPT-NEXT: call __truncsfhf2
; V8-OPT-NEXT: ld [%fp+-4], %o0
@@ -420,13 +425,14 @@ define void @test_fmul(ptr %p, ptr %q) nounwind {
; V8-UNOPT-LABEL: test_fmul:
; V8-UNOPT: ! %bb.0:
; V8-UNOPT-NEXT: save %sp, -104, %sp
-; V8-UNOPT-NEXT: call __extendhfsf2
-; V8-UNOPT-NEXT: lduh [%i0], %o0
-; V8-UNOPT-NEXT: st %f0, [%fp+-8] ! 4-byte Folded Spill
+; V8-UNOPT-NEXT: lduh [%i0], %i2
+; V8-UNOPT-NEXT: st %i2, [%fp+-12] ! 4-byte Folded Spill
; V8-UNOPT-NEXT: call __extendhfsf2
; V8-UNOPT-NEXT: lduh [%i1], %o0
-; V8-UNOPT-NEXT: fmovs %f0, %f1
-; V8-UNOPT-NEXT: ld [%fp+-8], %f0 ! 4-byte Folded Reload
+; V8-UNOPT-NEXT: ld [%fp+-12], %o0 ! 4-byte Folded Reload
+; V8-UNOPT-NEXT: call __extendhfsf2
+; V8-UNOPT-NEXT: st %f0, [%fp+-8]
+; V8-UNOPT-NEXT: ld [%fp+-8], %f1 ! 4-byte Folded Reload
; V8-UNOPT-NEXT: fmuls %f0, %f1, %f0
; V8-UNOPT-NEXT: st %f0, [%fp+-4]
; V8-UNOPT-NEXT: call __truncsfhf2
@@ -438,13 +444,14 @@ define void @test_fmul(ptr %p, ptr %q) nounwind {
; V9-LABEL: test_fmul:
; V9: ! %bb.0:
; V9-NEXT: save %sp, -104, %sp
+; V9-NEXT: lduh [%i0], %i2
; V9-NEXT: call __extendhfsf2
-; V9-NEXT: lduh [%i0], %o0
+; V9-NEXT: lduh [%i1], %o0
; V9-NEXT: st %f0, [%fp+-8] ! 4-byte Folded Spill
; V9-NEXT: call __extendhfsf2
-; V9-NEXT: lduh [%i1], %o0
+; V9-NEXT: mov %i2, %o0
; V9-NEXT: ld [%fp+-8], %f1 ! 4-byte Folded Reload
-; V9-NEXT: fmuls %f1, %f0, %f0
+; V9-NEXT: fmuls %f0, %f1, %f0
; V9-NEXT: st %f0, [%fp+-4]
; V9-NEXT: call __truncsfhf2
; V9-NEXT: ld [%fp+-4], %o0
@@ -455,14 +462,15 @@ define void @test_fmul(ptr %p, ptr %q) nounwind {
; SPARC64-LABEL: test_fmul:
; SPARC64: ! %bb.0:
; SPARC64-NEXT: save %sp, -192, %sp
+; SPARC64-NEXT: lduh [%i0], %i2
; SPARC64-NEXT: call __extendhfsf2
-; SPARC64-NEXT: lduh [%i0], %o0
+; SPARC64-NEXT: lduh [%i1], %o0
; SPARC64-NEXT: st %f0, [%fp+2043] ! 4-byte Folded Spill
; SPARC64-NEXT: call __extendhfsf2
-; SPARC64-NEXT: lduh [%i1], %o0
+; SPARC64-NEXT: mov %i2, %o0
; SPARC64-NEXT: ld [%fp+2043], %f1 ! 4-byte Folded Reload
; SPARC64-NEXT: call __truncsfhf2
-; SPARC64-NEXT: fmuls %f1, %f0, %f1
+; SPARC64-NEXT: fmuls %f0, %f1, %f1
; SPARC64-NEXT: sth %o0, [%i0]
; SPARC64-NEXT: ret
; SPARC64-NEXT: restore
diff --git a/llvm/test/CodeGen/SPARC/half.ll b/llvm/test/CodeGen/SPARC/half.ll
new file mode 100644
index 0000000000000..5db5176fe39cd
--- /dev/null
+++ b/llvm/test/CodeGen/SPARC/half.ll
@@ -0,0 +1,805 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+
+; RUN: llc %s -o - -mtriple=sparc-unknown-linux-gnu | FileCheck %s --check-prefixes=SPARC32
+; RUN: llc %s -o - -mtriple=sparc64-unknown-linux-gnu | FileCheck %s --check-prefixes=SPARC64
+
+; Tests for various operations on half precison float. Much of the test is
+; copied from test/CodeGen/X86/half.ll.
+
+define void @store(half %x, ptr %p) nounwind {
+; SPARC32-LABEL: store:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: retl
+; SPARC32-NEXT: sth %o0, [%o1]
+;
+; SPARC64-LABEL: store:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: retl
+; SPARC64-NEXT: sth %o0, [%o1]
+ store half %x, ptr %p
+ ret void
+}
+
+define half @return(ptr %p) nounwind {
+; SPARC32-LABEL: return:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: retl
+; SPARC32-NEXT: lduh [%o0], %o0
+;
+; SPARC64-LABEL: return:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: retl
+; SPARC64-NEXT: lduh [%o0], %o0
+ %r = load half, ptr %p
+ ret half %r
+}
+
+define dso_local double @loadd(ptr nocapture readonly %a) local_unnamed_addr nounwind {
+; SPARC32-LABEL: loadd:
+; SPARC32: ! %bb.0: ! %entry
+; SPARC32-NEXT: save %sp, -96, %sp
+; SPARC32-NEXT: call __extendhfsf2
+; SPARC32-NEXT: lduh [%i0+2], %o0
+; SPARC32-NEXT: fstod %f0, %f0
+; SPARC32-NEXT: ret
+; SPARC32-NEXT: restore
+;
+; SPARC64-LABEL: loadd:
+; SPARC64: ! %bb.0: ! %entry
+; SPARC64-NEXT: save %sp, -176, %sp
+; SPARC64-NEXT: call __extendhfsf2
+; SPARC64-NEXT: lduh [%i0+2], %o0
+; SPARC64-NEXT: fstod %f0, %f0
+; SPARC64-NEXT: ret
+; SPARC64-NEXT: restore
+entry:
+ %arrayidx = getelementptr inbounds i16, ptr %a, i64 1
+ %0 = load i16, ptr %arrayidx, align 2
+ %1 = tail call double @llvm.convert.from.fp16.f64(i16 %0)
+ ret double %1
+}
+
+define dso_local float @loadf(ptr nocapture readonly %a) local_unnamed_addr nounwind {
+; SPARC32-LABEL: loadf:
+; SPARC32: ! %bb.0: ! %entry
+; SPARC32-NEXT: save %sp, -96, %sp
+; SPARC32-NEXT: call __extendhfsf2
+; SPARC32-NEXT: lduh [%i0+2], %o0
+; SPARC32-NEXT: ret
+; SPARC32-NEXT: restore
+;
+; SPARC64-LABEL: loadf:
+; SPARC64: ! %bb.0: ! %entry
+; SPARC64-NEXT: save %sp, -176, %sp
+; SPARC64-NEXT: call __extendhfsf2
+; SPARC64-NEXT: lduh [%i0+2], %o0
+; SPARC64-NEXT: ret
+; SPARC64-NEXT: restore
+entry:
+ %arrayidx = getelementptr inbounds i16, ptr %a, i64 1
+ %0 = load i16, ptr %arrayidx, align 2
+ %1 = tail call float @llvm.convert.from.fp16.f32(i16 %0)
+ ret float %1
+}
+
+define dso_local void @stored(ptr nocapture %a, double %b) local_unnamed_addr nounwind {
+; SPARC32-LABEL: stored:
+; SPARC32: ! %bb.0: ! %entry
+; SPARC32-NEXT: save %sp, -112, %sp
+; SPARC32-NEXT: mov %i2, %i3
+; SPARC32-NEXT: mov %i1, %i2
+; SPARC32-NEXT: std %i2, [%fp+-8]
+; SPARC32-NEXT: ldd [%fp+-8], %f0
+; SPARC32-NEXT: std %f0, [%fp+-16]
+; SPARC32-NEXT: call __truncdfhf2
+; SPARC32-NEXT: ldd [%fp+-16], %o0
+; SPARC32-NEXT: sth %o0, [%i0]
+; SPARC32-NEXT: ret
+; SPARC32-NEXT: restore
+;
+; SPARC64-LABEL: stored:
+; SPARC64: ! %bb.0: ! %entry
+; SPARC64-NEXT: save %sp, -176, %sp
+; SPARC64-NEXT: fmovd %f2, %f0
+; SPARC64-NEXT: call __truncdfhf2
+; SPARC64-NEXT: nop
+; SPARC64-NEXT: sth %o0, [%i0]
+; SPARC64-NEXT: ret
+; SPARC64-NEXT: restore
+entry:
+ %0 = tail call i16 @llvm.convert.to.fp16.f64(double %b)
+ store i16 %0, ptr %a, align 2
+ ret void
+}
+
+define dso_local void @storef(ptr nocapture %a, float %b) local_unnamed_addr nounwind {
+; SPARC32-LABEL: storef:
+; SPARC32: ! %bb.0: ! %entry
+; SPARC32-NEXT: save %sp, -96, %sp
+; SPARC32-NEXT: call __truncsfhf2
+; SPARC32-NEXT: mov %i1, %o0
+; SPARC32-NEXT: sth %o0, [%i0]
+; SPARC32-NEXT: ret
+; SPARC32-NEXT: restore
+;
+; SPARC64-LABEL: storef:
+; SPARC64: ! %bb.0: ! %entry
+; SPARC64-NEXT: save %sp, -176, %sp
+; SPARC64-NEXT: fmovs %f3, %f1
+; SPARC64-NEXT: call __truncsfhf2
+; SPARC64-NEXT: nop
+; SPARC64-NEXT: sth %o0, [%i0]
+; SPARC64-NEXT: ret
+; SPARC64-NEXT: restore
+entry:
+ %0 = tail call i16 @llvm.convert.to.fp16.f32(float %b)
+ store i16 %0, ptr %a, align 2
+ ret void
+}
+
+define void @test_load_store(ptr %in, ptr %out) nounwind {
+; SPARC32-LABEL: test_load_store:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: lduh [%o0], %o0
+; SPARC32-NEXT: retl
+; SPARC32-NEXT: sth %o0, [%o1]
+;
+; SPARC64-LABEL: test_load_store:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: lduh [%o0], %o0
+; SPARC64-NEXT: retl
+; SPARC64-NEXT: sth %o0, [%o1]
+ %val = load half, ptr %in
+ store half %val, ptr %out
+ ret void
+}
+
+define i16 @test_bitcast_from_half(ptr %addr) nounwind {
+; SPARC32-LABEL: test_bitcast_from_half:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: retl
+; SPARC32-NEXT: lduh [%o0], %o0
+;
+; SPARC64-LABEL: test_bitcast_from_half:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: retl
+; SPARC64-NEXT: lduh [%o0], %o0
+ %val = load half, ptr %addr
+ %val_int = bitcast half %val to i16
+ ret i16 %val_int
+}
+
+define void @test_bitcast_to_half(ptr %addr, i16 %in) nounwind {
+; SPARC32-LABEL: test_bitcast_to_half:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: retl
+; SPARC32-NEXT: sth %o1, [%o0]
+;
+; SPARC64-LABEL: test_bitcast_to_half:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: retl
+; SPARC64-NEXT: sth %o1, [%o0]
+ %val_fp = bitcast i16 %in to half
+ store half %val_fp, ptr %addr
+ ret void
+}
+
+define half @from_bits(i16 %x) nounwind {
+; SPARC32-LABEL: from_bits:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: retl
+; SPARC32-NEXT: nop
+;
+; SPARC64-LABEL: from_bits:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: retl
+; SPARC64-NEXT: nop
+ %res = bitcast i16 %x to half
+ ret half %res
+}
+
+define i16 @to_bits(half %x) nounwind {
+; SPARC32-LABEL: to_bits:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: retl
+; SPARC32-NEXT: nop
+;
+; SPARC64-LABEL: to_bits:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: retl
+; SPARC64-NEXT: nop
+ %res = bitcast half %x to i16
+ ret i16 %res
+}
+
+define float @test_extend32(ptr %addr) nounwind {
+; SPARC32-LABEL: test_extend32:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: save %sp, -96, %sp
+; SPARC32-NEXT: call __extendhfsf2
+; SPARC32-NEXT: lduh [%i0], %o0
+; SPARC32-NEXT: ret
+; SPARC32-NEXT: restore
+;
+; SPARC64-LABEL: test_extend32:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: save %sp, -176, %sp
+; SPARC64-NEXT: call __extendhfsf2
+; SPARC64-NEXT: lduh [%i0], %o0
+; SPARC64-NEXT: ret
+; SPARC64-NEXT: restore
+ %val16 = load half, ptr %addr
+ %val32 = fpext half %val16 to float
+ ret float %val32
+}
+
+define double @test_extend64(ptr %addr) nounwind {
+; SPARC32-LABEL: test_extend64:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: save %sp, -96, %sp
+; SPARC32-NEXT: call __extendhfsf2
+; SPARC32-NEXT: lduh [%i0], %o0
+; SPARC32-NEXT: fstod %f0, %f0
+; SPARC32-NEXT: ret
+; SPARC32-NEXT: restore
+;
+; SPARC64-LABEL: test_extend64:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: save %sp, -176, %sp
+; SPARC64-NEXT: call __extendhfsf2
+; SPARC64-NEXT: lduh [%i0], %o0
+; SPARC64-NEXT: fstod %f0, %f0
+; SPARC64-NEXT: ret
+; SPARC64-NEXT: restore
+ %val16 = load half, ptr %addr
+ %val32 = fpext half %val16 to double
+ ret double %val32
+}
+
+define void @test_trunc32(float %in, ptr %addr) nounwind {
+; SPARC32-LABEL: test_trunc32:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: save %sp, -96, %sp
+; SPARC32-NEXT: call __truncsfhf2
+; SPARC32-NEXT: mov %i0, %o0
+; SPARC32-NEXT: sth %o0, [%i1]
+; SPARC32-NEXT: ret
+; SPARC32-NEXT: restore
+;
+; SPARC64-LABEL: test_trunc32:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: save %sp, -176, %sp
+; SPARC64-NEXT: call __truncsfhf2
+; SPARC64-NEXT: nop
+; SPARC64-NEXT: sth %o0, [%i1]
+; SPARC64-NEXT: ret
+; SPARC64-NEXT: restore
+ %val16 = fptrunc float %in to half
+ store half %val16, ptr %addr
+ ret void
+}
+
+define void @test_trunc64(double %in, ptr %addr) nounwind {
+; SPARC32-LABEL: test_trunc64:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: save %sp, -112, %sp
+; SPARC32-NEXT: ! kill: def $i1 killed $i1 killed $i0_i1 def $i0_i1
+; SPARC32-NEXT: ! kill: def $i0 killed $i0 killed $i0_i1 def $i0_i1
+; SPARC32-NEXT: std %i0, [%fp+-8]
+; SPARC32-NEXT: ldd [%fp+-8], %f0
+; SPARC32-NEXT: std %f0, [%fp+-16]
+; SPARC32-NEXT: call __truncdfhf2
+; SPARC32-NEXT: ldd [%fp+-16], %o0
+; SPARC32-NEXT: sth %o0, [%i2]
+; SPARC32-NEXT: ret
+; SPARC32-NEXT: restore
+;
+; SPARC64-LABEL: test_trunc64:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: save %sp, -176, %sp
+; SPARC64-NEXT: call __truncdfhf2
+; SPARC64-NEXT: nop
+; SPARC64-NEXT: sth %o0, [%i1]
+; SPARC64-NEXT: ret
+; SPARC64-NEXT: restore
+ %val16 = fptrunc double %in to half
+ store half %val16, ptr %addr
+ ret void
+}
+
+define i64 @test_fptosi_i64(ptr %p) nounwind {
+; SPARC32-LABEL: test_fptosi_i64:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: save %sp, -96, %sp
+; SPARC32-NEXT: call __extendhfsf2
+; SPARC32-NEXT: lduh [%i0], %o0
+; SPARC32-NEXT: st %f0, [%fp+-4]
+; SPARC32-NEXT: call __fixsfdi
+; SPARC32-NEXT: ld [%fp+-4], %o0
+; SPARC32-NEXT: mov %o0, %i0
+; SPARC32-NEXT: ret
+; SPARC32-NEXT: restore %g0, %o1, %o1
+;
+; SPARC64-LABEL: test_fptosi_i64:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: save %sp, -192, %sp
+; SPARC64-NEXT: call __extendhfsf2
+; SPARC64-NEXT: lduh [%i0], %o0
+; SPARC64-NEXT: fstox %f0, %f0
+; SPARC64-NEXT: std %f0, [%fp+2039]
+; SPARC64-NEXT: ldx [%fp+2039], %i0
+; SPARC64-NEXT: ret
+; SPARC64-NEXT: restore
+ %a = load half, ptr %p, align 2
+ %r = fptosi half %a to i64
+ ret i64 %r
+}
+
+define void @test_sitofp_i64(i64 %a, ptr %p) nounwind {
+; SPARC32-LABEL: test_sitofp_i64:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: save %sp, -96, %sp
+; SPARC32-NEXT: mov %i1, %o1
+; SPARC32-NEXT: call __floatdisf
+; SPARC32-NEXT: mov %i0, %o0
+; SPARC32-NEXT: st %f0, [%fp+-4]
+; SPARC32-NEXT: call __truncsfhf2
+; SPARC32-NEXT: ld [%fp+-4], %o0
+; SPARC32-NEXT: sth %o0, [%i2]
+; SPARC32-NEXT: ret
+; SPARC32-NEXT: restore
+;
+; SPARC64-LABEL: test_sitofp_i64:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: save %sp, -192, %sp
+; SPARC64-NEXT: stx %i0, [%fp+2039]
+; SPARC64-NEXT: ldd [%fp+2039], %f0
+; SPARC64-NEXT: call __truncsfhf2
+; SPARC64-NEXT: fxtos %f0, %f1
+; SPARC64-NEXT: sth %o0, [%i1]
+; SPARC64-NEXT: ret
+; SPARC64-NEXT: restore
+ %r = sitofp i64 %a to half
+ store half %r, ptr %p
+ ret void
+}
+
+define i64 @test_fptoui_i64(ptr %p) nounwind {
+; SPARC32-LABEL: test_fptoui_i64:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: save %sp, -96, %sp
+; SPARC32-NEXT: call __extendhfsf2
+; SPARC32-NEXT: lduh [%i0], %o0
+; SPARC32-NEXT: st %f0, [%fp+-4]
+; SPARC32-NEXT: call __fixunssfdi
+; SPARC32-NEXT: ld [%fp+-4], %o0
+; SPARC32-NEXT: mov %o0, %i0
+; SPARC32-NEXT: ret
+; SPARC32-NEXT: restore %g0, %o1, %o1
+;
+; SPARC64-LABEL: test_fptoui_i64:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: save %sp, -192, %sp
+; SPARC64-NEXT: call __extendhfsf2
+; SPARC64-NEXT: lduh [%i0], %o0
+; SPARC64-NEXT: sethi %h44(.LCPI17_0), %i0
+; SPARC64-NEXT: add %i0, %m44(.LCPI17_0), %i0
+; SPARC64-NEXT: sllx %i0, 12, %i0
+; SPARC64-NEXT: ld [%i0+%l44(.LCPI17_0)], %f1
+; SPARC64-NEXT: fsubs %f0, %f1, %f2
+; SPARC64-NEXT: fstox %f2, %f2
+; SPARC64-NEXT: std %f2, [%fp+2031]
+; SPARC64-NEXT: fstox %f0, %f2
+; SPARC64-NEXT: std %f2, [%fp+2039]
+; SPARC64-NEXT: ldx [%fp+2031], %i0
+; SPARC64-NEXT: sethi 0, %i1
+; SPARC64-NEXT: or %i1, 0, %i1
+; SPARC64-NEXT: sethi 2097152, %i2
+; SPARC64-NEXT: or %i2, 0, %i2
+; SPARC64-NEXT: sllx %i2, 32, %i2
+; SPARC64-NEXT: ldx [%fp+2039], %i3
+; SPARC64-NEXT: or %i2, %i1, %i1
+; SPARC64-NEXT: xor %i0, %i1, %i0
+; SPARC64-NEXT: fcmps %fcc0, %f0, %f1
+; SPARC64-NEXT: movl %fcc0, %i3, %i0
+; SPARC64-NEXT: ret
+; SPARC64-NEXT: restore
+ %a = load half, ptr %p, align 2
+ %r = fptoui half %a to i64
+ ret i64 %r
+}
+
+define void @test_uitofp_i64(i64 %a, ptr %p) nounwind {
+; SPARC32-LABEL: test_uitofp_i64:
+; SPARC32: ! %bb.0:
+; SPARC32-NEXT: save %sp, -96, %sp
+; SPARC32-NEXT: mov %i1, %o1
+; SPARC32-NEXT: call __floatundisf
+; SPARC32-NEXT: mov %i0, %o0
+; SPARC32-NEXT: st %f0, [%fp+-4]
+; SPARC32-NEXT: call __truncsfhf2
+; SPARC32-NEXT: ld [%fp+-4], %o0
+; SPARC32-NEXT: sth %o0, [%i2]
+; SPARC32-NEXT: ret
+; SPARC32-NEXT: restore
+;
+; SPARC64-LABEL: test_uitofp_i64:
+; SPARC64: ! %bb.0:
+; SPARC64-NEXT: save %sp, -192, %sp
+; SPARC64-NEXT: stx %i0, [%fp+2031]
+; SPARC64-NEXT: srlx %i0, 1, %i2
+; SPARC64-NEXT: and %i0, 1, %i3
+; SPARC64-NEXT: or %i3, %i2, %i2
+; SPARC64-NEXT: stx %i2, [%fp+2039]
+; SPARC64-NEXT: ldd [%fp+2031], %f0
+; SPARC64-NEXT: ldd [%fp+2039], %f2
+; SPARC64-NEXT: fxtos %f0, %f1
+; SPARC64-NEXT: fxtos %f2, %f0
+; SPARC64-NEXT: fadds %f0, %f0, %f0
+; SPARC64-NEXT: call __truncsfhf2
+; SPARC64-NEXT: fmovrslz %i0, %f0, %f1
+; SPARC64-NEXT: sth %o0, [%i1]
+; SPARC64-NEXT: ret
+; SPARC64-NEXT: restore
+ %r = uitofp i...
[truncated]
|
half
to use soft promotion rather than PromoteFloat
half
to use soft promotion rather than PromoteFloat
2c77ec7
to
da54e4e
Compare
da54e4e
to
2b94326
Compare
`half` currently uses the default legalization of promoting to a `f32`; however, this implementation implements math in a way that results in incorrect rounding. Switch to the soft promote implementation, which does not have this problem. The SPARC ABI does not specify a `_Float16` type, so there is no concern with keeping interface compatibility. Fixes the SPARC portion of [1]. [1]: llvm#97975
2b94326
to
86841fa
Compare
half
currently uses the default legalization of promoting to af32
; however, this implementation implements math in a way that results in incorrect rounding. Switch to the soft promote implementation, which does not have this problem.The SPARC ABI does not specify a
_Float16
type, so there is no concern with keeping interface compatibility.Fixes the SPARC part of #97975
Fixes the SPARC part of #97981