[llvm] [AVR] Change `half` to use `softPromoteHalfType` (PR #152783)
Trevor Gross via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 8 12:45:59 PDT 2025
https://github.com/tgross35 created https://github.com/llvm/llvm-project/pull/152783
The default `half` legalization has some issues with quieting NaNs and carrying excess precision. As has been done for various other targets, update AVR to use `softPromoteHalfType` which avoids these issues.
The most obvious corrected test below is `test_load_store`, which no longer contains calls to extend and trunc (this passing through libcalls means that `f16` does not round trip).
>From d0f6eff3d59da7ba0ebaac79e7453b4b5c30f0f3 Mon Sep 17 00:00:00 2001
From: Trevor Gross <tmgross at umich.edu>
Date: Fri, 8 Aug 2025 08:03:18 -0500
Subject: [PATCH 1/2] [AVR] Add a test for half support (NFC)
To ensure that the current support doesn't regress, add a version of the
`half.ll` test present on other targets to AVR.
---
llvm/test/CodeGen/AVR/half.ll | 750 ++++++++++++++++++++++++++++++++++
1 file changed, 750 insertions(+)
create mode 100644 llvm/test/CodeGen/AVR/half.ll
diff --git a/llvm/test/CodeGen/AVR/half.ll b/llvm/test/CodeGen/AVR/half.ll
new file mode 100644
index 0000000000000..8af9d18eac8ff
--- /dev/null
+++ b/llvm/test/CodeGen/AVR/half.ll
@@ -0,0 +1,750 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc %s -o - -mtriple=avr | FileCheck %s
+
+; 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 {
+; CHECK-LABEL: store:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: mov r30, r20
+; CHECK-NEXT: mov r31, r21
+; CHECK-NEXT: std Z+1, r23
+; CHECK-NEXT: st Z, r22
+; CHECK-NEXT: ret
+ store half %x, ptr %p
+ ret void
+}
+
+define half @return(ptr %p) nounwind {
+; CHECK-LABEL: return:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: mov r30, r24
+; CHECK-NEXT: mov r31, r25
+; CHECK-NEXT: ld r22, Z
+; CHECK-NEXT: ldd r23, Z+1
+; CHECK-NEXT: ret
+ %r = load half, ptr %p
+ ret half %r
+}
+
+define dso_local double @loadd(ptr nocapture readonly %a) local_unnamed_addr nounwind {
+; CHECK-LABEL: loadd:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: mov r30, r24
+; CHECK-NEXT: mov r31, r25
+; CHECK-NEXT: ldd r24, Z+2
+; CHECK-NEXT: ldd r25, Z+3
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __extendsfdf2
+; CHECK-NEXT: ret
+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 {
+; CHECK-LABEL: loadf:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: mov r30, r24
+; CHECK-NEXT: mov r31, r25
+; CHECK-NEXT: ldd r24, Z+2
+; CHECK-NEXT: ldd r25, Z+3
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: ret
+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 {
+; CHECK-LABEL: stored:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: push r16
+; CHECK-NEXT: push r17
+; CHECK-NEXT: mov r30, r22
+; CHECK-NEXT: mov r31, r23
+; CHECK-NEXT: mov r22, r20
+; CHECK-NEXT: mov r23, r21
+; CHECK-NEXT: mov r20, r18
+; CHECK-NEXT: mov r21, r19
+; CHECK-NEXT: mov r18, r16
+; CHECK-NEXT: mov r19, r17
+; CHECK-NEXT: mov r16, r24
+; CHECK-NEXT: mov r17, r25
+; CHECK-NEXT: mov r24, r30
+; CHECK-NEXT: mov r25, r31
+; CHECK-NEXT: rcall __truncdfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+1, r25
+; CHECK-NEXT: st Z, r24
+; CHECK-NEXT: pop r17
+; CHECK-NEXT: pop r16
+; CHECK-NEXT: ret
+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 {
+; CHECK-LABEL: storef:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: push r16
+; CHECK-NEXT: push r17
+; CHECK-NEXT: mov r18, r22
+; CHECK-NEXT: mov r19, r23
+; CHECK-NEXT: mov r16, r24
+; CHECK-NEXT: mov r17, r25
+; CHECK-NEXT: mov r22, r20
+; CHECK-NEXT: mov r23, r21
+; CHECK-NEXT: mov r24, r18
+; CHECK-NEXT: mov r25, r19
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+1, r25
+; CHECK-NEXT: st Z, r24
+; CHECK-NEXT: pop r17
+; CHECK-NEXT: pop r16
+; CHECK-NEXT: ret
+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 {
+; CHECK-LABEL: test_load_store:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: push r16
+; CHECK-NEXT: push r17
+; CHECK-NEXT: mov r16, r22
+; CHECK-NEXT: mov r17, r23
+; CHECK-NEXT: mov r30, r24
+; CHECK-NEXT: mov r31, r25
+; CHECK-NEXT: ld r24, Z
+; CHECK-NEXT: ldd r25, Z+1
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+1, r25
+; CHECK-NEXT: st Z, r24
+; CHECK-NEXT: pop r17
+; CHECK-NEXT: pop r16
+; CHECK-NEXT: ret
+ %val = load half, ptr %in
+ store half %val, ptr %out
+ ret void
+}
+
+define i16 @test_bitcast_from_half(ptr %addr) nounwind {
+; CHECK-LABEL: test_bitcast_from_half:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: mov r30, r24
+; CHECK-NEXT: mov r31, r25
+; CHECK-NEXT: ld r24, Z
+; CHECK-NEXT: ldd r25, Z+1
+; CHECK-NEXT: ret
+ %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 {
+; CHECK-LABEL: test_bitcast_to_half:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: mov r30, r24
+; CHECK-NEXT: mov r31, r25
+; CHECK-NEXT: std Z+1, r23
+; CHECK-NEXT: st Z, r22
+; CHECK-NEXT: ret
+ %val_fp = bitcast i16 %in to half
+ store half %val_fp, ptr %addr
+ ret void
+}
+
+define half @from_bits(i16 %x) nounwind {
+; CHECK-LABEL: from_bits:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: mov r22, r24
+; CHECK-NEXT: mov r23, r25
+; CHECK-NEXT: ret
+ %res = bitcast i16 %x to half
+ ret half %res
+}
+
+define i16 @to_bits(half %x) nounwind {
+; CHECK-LABEL: to_bits:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: mov r24, r22
+; CHECK-NEXT: mov r25, r23
+; CHECK-NEXT: ret
+ %res = bitcast half %x to i16
+ ret i16 %res
+}
+
+define float @test_extend32(ptr %addr) nounwind {
+; CHECK-LABEL: test_extend32:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: mov r30, r24
+; CHECK-NEXT: mov r31, r25
+; CHECK-NEXT: ld r24, Z
+; CHECK-NEXT: ldd r25, Z+1
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: ret
+ %val16 = load half, ptr %addr
+ %val32 = fpext half %val16 to float
+ ret float %val32
+}
+
+define double @test_extend64(ptr %addr) nounwind {
+; CHECK-LABEL: test_extend64:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: mov r30, r24
+; CHECK-NEXT: mov r31, r25
+; CHECK-NEXT: ld r24, Z
+; CHECK-NEXT: ldd r25, Z+1
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __extendsfdf2
+; CHECK-NEXT: ret
+ %val16 = load half, ptr %addr
+ %val32 = fpext half %val16 to double
+ ret double %val32
+}
+
+define void @test_trunc32(float %in, ptr %addr) nounwind {
+; CHECK-LABEL: test_trunc32:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: push r16
+; CHECK-NEXT: push r17
+; CHECK-NEXT: mov r16, r20
+; CHECK-NEXT: mov r17, r21
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+1, r25
+; CHECK-NEXT: st Z, r24
+; CHECK-NEXT: pop r17
+; CHECK-NEXT: pop r16
+; CHECK-NEXT: ret
+ %val16 = fptrunc float %in to half
+ store half %val16, ptr %addr
+ ret void
+}
+
+define void @test_trunc64(double %in, ptr %addr) nounwind {
+; CHECK-LABEL: test_trunc64:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: rcall __truncdfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+1, r25
+; CHECK-NEXT: st Z, r24
+; CHECK-NEXT: ret
+ %val16 = fptrunc double %in to half
+ store half %val16, ptr %addr
+ ret void
+}
+
+define i64 @test_fptosi_i64(ptr %p) nounwind {
+; CHECK-LABEL: test_fptosi_i64:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: mov r30, r24
+; CHECK-NEXT: mov r31, r25
+; CHECK-NEXT: ld r24, Z
+; CHECK-NEXT: ldd r25, Z+1
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __fixsfdi
+; CHECK-NEXT: ret
+ %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 {
+; CHECK-LABEL: test_sitofp_i64:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: rcall __floatdisf
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+1, r25
+; CHECK-NEXT: st Z, r24
+; CHECK-NEXT: ret
+ %r = sitofp i64 %a to half
+ store half %r, ptr %p
+ ret void
+}
+
+define i64 @test_fptoui_i64(ptr %p) nounwind {
+; CHECK-LABEL: test_fptoui_i64:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: mov r30, r24
+; CHECK-NEXT: mov r31, r25
+; CHECK-NEXT: ld r24, Z
+; CHECK-NEXT: ldd r25, Z+1
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __fixunssfdi
+; CHECK-NEXT: ret
+ %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 {
+; CHECK-LABEL: test_uitofp_i64:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: rcall __floatundisf
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+1, r25
+; CHECK-NEXT: st Z, r24
+; CHECK-NEXT: ret
+ %r = uitofp i64 %a to half
+ store half %r, ptr %p
+ ret void
+}
+
+define <4 x float> @test_extend32_vec4(ptr %p) nounwind {
+; CHECK-LABEL: test_extend32_vec4:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: push r14
+; CHECK-NEXT: push r15
+; CHECK-NEXT: push r16
+; CHECK-NEXT: push r17
+; CHECK-NEXT: mov r16, r24
+; CHECK-NEXT: mov r17, r25
+; CHECK-NEXT: mov r30, r22
+; CHECK-NEXT: mov r31, r23
+; CHECK-NEXT: ldd r24, Z+6
+; CHECK-NEXT: ldd r25, Z+7
+; CHECK-NEXT: mov r14, r30
+; CHECK-NEXT: mov r15, r31
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+15, r25
+; CHECK-NEXT: std Z+14, r24
+; CHECK-NEXT: std Z+13, r23
+; CHECK-NEXT: std Z+12, r22
+; CHECK-NEXT: mov r30, r14
+; CHECK-NEXT: mov r31, r15
+; CHECK-NEXT: ldd r24, Z+4
+; CHECK-NEXT: ldd r25, Z+5
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+11, r25
+; CHECK-NEXT: std Z+10, r24
+; CHECK-NEXT: std Z+9, r23
+; CHECK-NEXT: std Z+8, r22
+; CHECK-NEXT: mov r30, r14
+; CHECK-NEXT: mov r31, r15
+; CHECK-NEXT: ldd r24, Z+2
+; CHECK-NEXT: ldd r25, Z+3
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+7, r25
+; CHECK-NEXT: std Z+6, r24
+; CHECK-NEXT: std Z+5, r23
+; CHECK-NEXT: std Z+4, r22
+; CHECK-NEXT: mov r30, r14
+; CHECK-NEXT: mov r31, r15
+; CHECK-NEXT: ld r24, Z
+; CHECK-NEXT: ldd r25, Z+1
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+3, r25
+; CHECK-NEXT: std Z+2, r24
+; CHECK-NEXT: std Z+1, r23
+; CHECK-NEXT: st Z, r22
+; CHECK-NEXT: pop r17
+; CHECK-NEXT: pop r16
+; CHECK-NEXT: pop r15
+; CHECK-NEXT: pop r14
+; CHECK-NEXT: ret
+ %a = load <4 x half>, ptr %p, align 8
+ %b = fpext <4 x half> %a to <4 x float>
+ ret <4 x float> %b
+}
+
+define <4 x double> @test_extend64_vec4(ptr %p) nounwind {
+; CHECK-LABEL: test_extend64_vec4:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: push r14
+; CHECK-NEXT: push r15
+; CHECK-NEXT: push r16
+; CHECK-NEXT: push r17
+; CHECK-NEXT: mov r16, r24
+; CHECK-NEXT: mov r17, r25
+; CHECK-NEXT: mov r30, r22
+; CHECK-NEXT: mov r31, r23
+; CHECK-NEXT: ldd r24, Z+6
+; CHECK-NEXT: ldd r25, Z+7
+; CHECK-NEXT: mov r14, r30
+; CHECK-NEXT: mov r15, r31
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __extendsfdf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+31, r25
+; CHECK-NEXT: std Z+30, r24
+; CHECK-NEXT: std Z+29, r23
+; CHECK-NEXT: std Z+28, r22
+; CHECK-NEXT: std Z+27, r21
+; CHECK-NEXT: std Z+26, r20
+; CHECK-NEXT: std Z+25, r19
+; CHECK-NEXT: std Z+24, r18
+; CHECK-NEXT: mov r30, r14
+; CHECK-NEXT: mov r31, r15
+; CHECK-NEXT: ldd r24, Z+4
+; CHECK-NEXT: ldd r25, Z+5
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __extendsfdf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+23, r25
+; CHECK-NEXT: std Z+22, r24
+; CHECK-NEXT: std Z+21, r23
+; CHECK-NEXT: std Z+20, r22
+; CHECK-NEXT: std Z+19, r21
+; CHECK-NEXT: std Z+18, r20
+; CHECK-NEXT: std Z+17, r19
+; CHECK-NEXT: std Z+16, r18
+; CHECK-NEXT: mov r30, r14
+; CHECK-NEXT: mov r31, r15
+; CHECK-NEXT: ldd r24, Z+2
+; CHECK-NEXT: ldd r25, Z+3
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __extendsfdf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+15, r25
+; CHECK-NEXT: std Z+14, r24
+; CHECK-NEXT: std Z+13, r23
+; CHECK-NEXT: std Z+12, r22
+; CHECK-NEXT: std Z+11, r21
+; CHECK-NEXT: std Z+10, r20
+; CHECK-NEXT: std Z+9, r19
+; CHECK-NEXT: std Z+8, r18
+; CHECK-NEXT: mov r30, r14
+; CHECK-NEXT: mov r31, r15
+; CHECK-NEXT: ld r24, Z
+; CHECK-NEXT: ldd r25, Z+1
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __extendsfdf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+7, r25
+; CHECK-NEXT: std Z+6, r24
+; CHECK-NEXT: std Z+5, r23
+; CHECK-NEXT: std Z+4, r22
+; CHECK-NEXT: std Z+3, r21
+; CHECK-NEXT: std Z+2, r20
+; CHECK-NEXT: std Z+1, r19
+; CHECK-NEXT: st Z, r18
+; CHECK-NEXT: pop r17
+; CHECK-NEXT: pop r16
+; CHECK-NEXT: pop r15
+; CHECK-NEXT: pop r14
+; CHECK-NEXT: ret
+ %a = load <4 x half>, ptr %p, align 8
+ %b = fpext <4 x half> %a to <4 x double>
+ ret <4 x double> %b
+}
+
+define void @test_trunc32_vec4(<4 x float> %a, ptr %p) nounwind {
+; CHECK-LABEL: test_trunc32_vec4:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: push r4
+; CHECK-NEXT: push r5
+; CHECK-NEXT: push r6
+; CHECK-NEXT: push r7
+; CHECK-NEXT: mov r6, r20
+; CHECK-NEXT: mov r7, r21
+; CHECK-NEXT: mov r4, r18
+; CHECK-NEXT: mov r5, r19
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r30, r8
+; CHECK-NEXT: mov r31, r9
+; CHECK-NEXT: std Z+7, r25
+; CHECK-NEXT: std Z+6, r24
+; CHECK-NEXT: mov r22, r4
+; CHECK-NEXT: mov r23, r5
+; CHECK-NEXT: mov r24, r6
+; CHECK-NEXT: mov r25, r7
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r30, r8
+; CHECK-NEXT: mov r31, r9
+; CHECK-NEXT: std Z+5, r25
+; CHECK-NEXT: std Z+4, r24
+; CHECK-NEXT: mov r22, r14
+; CHECK-NEXT: mov r23, r15
+; CHECK-NEXT: mov r24, r16
+; CHECK-NEXT: mov r25, r17
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r30, r8
+; CHECK-NEXT: mov r31, r9
+; CHECK-NEXT: std Z+3, r25
+; CHECK-NEXT: std Z+2, r24
+; CHECK-NEXT: mov r22, r10
+; CHECK-NEXT: mov r23, r11
+; CHECK-NEXT: mov r24, r12
+; CHECK-NEXT: mov r25, r13
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r30, r8
+; CHECK-NEXT: mov r31, r9
+; CHECK-NEXT: std Z+1, r25
+; CHECK-NEXT: st Z, r24
+; CHECK-NEXT: pop r7
+; CHECK-NEXT: pop r6
+; CHECK-NEXT: pop r5
+; CHECK-NEXT: pop r4
+; CHECK-NEXT: ret
+ %v = fptrunc <4 x float> %a to <4 x half>
+ store <4 x half> %v, ptr %p
+ ret void
+}
+
+define void @test_trunc64_vec4(<4 x double> %a, ptr %p) nounwind {
+; CHECK-LABEL: test_trunc64_vec4:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: push r16
+; CHECK-NEXT: push r17
+; CHECK-NEXT: push r28
+; CHECK-NEXT: push r29
+; CHECK-NEXT: in r28, 61
+; CHECK-NEXT: in r29, 62
+; CHECK-NEXT: ldd r18, Y+31
+; CHECK-NEXT: ldd r19, Y+32
+; CHECK-NEXT: ldd r20, Y+33
+; CHECK-NEXT: ldd r21, Y+34
+; CHECK-NEXT: ldd r22, Y+35
+; CHECK-NEXT: ldd r23, Y+36
+; CHECK-NEXT: ldd r24, Y+37
+; CHECK-NEXT: ldd r25, Y+38
+; CHECK-NEXT: rcall __truncdfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: ldd r18, Y+39
+; CHECK-NEXT: ldd r19, Y+40
+; CHECK-NEXT: mov r30, r18
+; CHECK-NEXT: mov r31, r19
+; CHECK-NEXT: std Z+7, r25
+; CHECK-NEXT: std Z+6, r24
+; CHECK-NEXT: mov r16, r30
+; CHECK-NEXT: mov r17, r31
+; CHECK-NEXT: ldd r18, Y+23
+; CHECK-NEXT: ldd r19, Y+24
+; CHECK-NEXT: ldd r20, Y+25
+; CHECK-NEXT: ldd r21, Y+26
+; CHECK-NEXT: ldd r22, Y+27
+; CHECK-NEXT: ldd r23, Y+28
+; CHECK-NEXT: ldd r24, Y+29
+; CHECK-NEXT: ldd r25, Y+30
+; CHECK-NEXT: rcall __truncdfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+5, r25
+; CHECK-NEXT: std Z+4, r24
+; CHECK-NEXT: ldd r18, Y+15
+; CHECK-NEXT: ldd r19, Y+16
+; CHECK-NEXT: ldd r20, Y+17
+; CHECK-NEXT: ldd r21, Y+18
+; CHECK-NEXT: ldd r22, Y+19
+; CHECK-NEXT: ldd r23, Y+20
+; CHECK-NEXT: ldd r24, Y+21
+; CHECK-NEXT: ldd r25, Y+22
+; CHECK-NEXT: rcall __truncdfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+3, r25
+; CHECK-NEXT: std Z+2, r24
+; CHECK-NEXT: ldd r18, Y+7
+; CHECK-NEXT: ldd r19, Y+8
+; CHECK-NEXT: ldd r20, Y+9
+; CHECK-NEXT: ldd r21, Y+10
+; CHECK-NEXT: ldd r22, Y+11
+; CHECK-NEXT: ldd r23, Y+12
+; CHECK-NEXT: ldd r24, Y+13
+; CHECK-NEXT: ldd r25, Y+14
+; CHECK-NEXT: rcall __truncdfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: std Z+1, r25
+; CHECK-NEXT: st Z, r24
+; CHECK-NEXT: pop r29
+; CHECK-NEXT: pop r28
+; CHECK-NEXT: pop r17
+; CHECK-NEXT: pop r16
+; CHECK-NEXT: ret
+ %v = fptrunc <4 x double> %a to <4 x half>
+ store <4 x half> %v, ptr %p
+ ret void
+}
+
+define float @test_sitofp_fadd_i32(i32 %a, ptr %b) nounwind {
+; CHECK-LABEL: test_sitofp_fadd_i32:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: push r10
+; CHECK-NEXT: push r11
+; CHECK-NEXT: push r12
+; CHECK-NEXT: push r13
+; CHECK-NEXT: push r14
+; CHECK-NEXT: push r15
+; CHECK-NEXT: push r16
+; CHECK-NEXT: push r17
+; CHECK-NEXT: mov r16, r24
+; CHECK-NEXT: mov r17, r25
+; CHECK-NEXT: mov r14, r22
+; CHECK-NEXT: mov r15, r23
+; CHECK-NEXT: mov r30, r20
+; CHECK-NEXT: mov r31, r21
+; CHECK-NEXT: ld r24, Z
+; CHECK-NEXT: ldd r25, Z+1
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: mov r12, r22
+; CHECK-NEXT: mov r13, r23
+; CHECK-NEXT: mov r10, r24
+; CHECK-NEXT: mov r11, r25
+; CHECK-NEXT: mov r22, r14
+; CHECK-NEXT: mov r23, r15
+; CHECK-NEXT: mov r24, r16
+; CHECK-NEXT: mov r25, r17
+; CHECK-NEXT: rcall __floatsisf
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: mov r18, r22
+; CHECK-NEXT: mov r19, r23
+; CHECK-NEXT: mov r20, r24
+; CHECK-NEXT: mov r21, r25
+; CHECK-NEXT: mov r22, r12
+; CHECK-NEXT: mov r23, r13
+; CHECK-NEXT: mov r24, r10
+; CHECK-NEXT: mov r25, r11
+; CHECK-NEXT: rcall __addsf3
+; CHECK-NEXT: pop r17
+; CHECK-NEXT: pop r16
+; CHECK-NEXT: pop r15
+; CHECK-NEXT: pop r14
+; CHECK-NEXT: pop r13
+; CHECK-NEXT: pop r12
+; CHECK-NEXT: pop r11
+; CHECK-NEXT: pop r10
+; CHECK-NEXT: ret
+ %tmp0 = load half, ptr %b
+ %tmp1 = sitofp i32 %a to half
+ %tmp2 = fadd half %tmp0, %tmp1
+ %tmp3 = fpext half %tmp2 to float
+ ret float %tmp3
+}
+
+define half @PR40273(half) nounwind {
+; CHECK-LABEL: PR40273:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: push r16
+; CHECK-NEXT: push r17
+; CHECK-NEXT: mov r24, r22
+; CHECK-NEXT: mov r25, r23
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: ldi r16, 0
+; CHECK-NEXT: ldi r17, 0
+; CHECK-NEXT: mov r18, r16
+; CHECK-NEXT: mov r19, r17
+; CHECK-NEXT: mov r20, r16
+; CHECK-NEXT: mov r21, r17
+; CHECK-NEXT: rcall __nesf2
+; CHECK-NEXT: cpi r24, 0
+; CHECK-NEXT: brne .LBB24_2
+; CHECK-NEXT: ; %bb.1:
+; CHECK-NEXT: mov r24, r16
+; CHECK-NEXT: mov r25, r17
+; CHECK-NEXT: rjmp .LBB24_3
+; CHECK-NEXT: .LBB24_2:
+; CHECK-NEXT: ldi r24, 128
+; CHECK-NEXT: ldi r25, 63
+; CHECK-NEXT: .LBB24_3:
+; CHECK-NEXT: mov r22, r16
+; CHECK-NEXT: mov r23, r17
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r22, r24
+; CHECK-NEXT: mov r23, r25
+; CHECK-NEXT: pop r17
+; CHECK-NEXT: pop r16
+; CHECK-NEXT: ret
+ %2 = fcmp une half %0, 0xH0000
+ %3 = uitofp i1 %2 to half
+ ret half %3
+}
+
+define half @fabs(half %x) nounwind {
+; CHECK-LABEL: fabs:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: andi r23, 127
+; CHECK-NEXT: ldi r24, 0
+; CHECK-NEXT: ldi r25, 0
+; CHECK-NEXT: ret
+ %a = call half @llvm.fabs.f16(half %x)
+ ret half %a
+}
+
+define half @fcopysign(half %x, half %y) nounwind {
+; CHECK-LABEL: fcopysign:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: push r16
+; CHECK-NEXT: push r17
+; CHECK-NEXT: mov r16, r18
+; CHECK-NEXT: mov r17, r19
+; CHECK-NEXT: mov r24, r22
+; CHECK-NEXT: mov r25, r23
+; CHECK-NEXT: rcall __extendhfsf2
+; CHECK-NEXT: andi r16, 0
+; CHECK-NEXT: andi r17, 128
+; CHECK-NEXT: andi r25, 127
+; CHECK-NEXT: or r24, r16
+; CHECK-NEXT: or r25, r17
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r22, r24
+; CHECK-NEXT: mov r23, r25
+; CHECK-NEXT: pop r17
+; CHECK-NEXT: pop r16
+; CHECK-NEXT: ret
+ %a = call half @llvm.copysign.f16(half %x, half %y)
+ ret half %a
+}
>From 313ca5ebf5bcba79e95eefa4af4c90e555d5ee4f Mon Sep 17 00:00:00 2001
From: Trevor Gross <tmgross at umich.edu>
Date: Fri, 8 Aug 2025 14:36:25 -0500
Subject: [PATCH 2/2] [AVR] Change `half` to use `softPromoteHalfType`
The default `half` legalization has some issues with quieting NaNs and
carrying excess precision. As has been done for various other targets,
update AVR to use `softPromoteHalfType` which avoids these issues.
The most obvious corrected test below is `test_load_store`, which no
longer contains calls to extend and trunc (which would cause
roundtripping to fail).
---
llvm/lib/Target/AVR/AVRISelLowering.h | 2 +
llvm/test/CodeGen/AVR/half.ll | 141 +++++++-------------------
llvm/test/CodeGen/AVR/llvm.sincos.ll | 70 ++++++-------
3 files changed, 69 insertions(+), 144 deletions(-)
diff --git a/llvm/lib/Target/AVR/AVRISelLowering.h b/llvm/lib/Target/AVR/AVRISelLowering.h
index 2ae22b2d8af6c..301ce9c34a783 100644
--- a/llvm/lib/Target/AVR/AVRISelLowering.h
+++ b/llvm/lib/Target/AVR/AVRISelLowering.h
@@ -94,6 +94,8 @@ class AVRTargetLowering : public TargetLowering {
return ShiftLegalizationStrategy::LowerToLibcall;
}
+ bool softPromoteHalfType() const override { return true; }
+
private:
SDValue getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &AVRcc,
SelectionDAG &DAG, SDLoc dl) const;
diff --git a/llvm/test/CodeGen/AVR/half.ll b/llvm/test/CodeGen/AVR/half.ll
index 8af9d18eac8ff..fa24455ae1596 100644
--- a/llvm/test/CodeGen/AVR/half.ll
+++ b/llvm/test/CodeGen/AVR/half.ll
@@ -7,10 +7,10 @@
define void @store(half %x, ptr %p) nounwind {
; CHECK-LABEL: store:
; CHECK: ; %bb.0:
-; CHECK-NEXT: mov r30, r20
-; CHECK-NEXT: mov r31, r21
-; CHECK-NEXT: std Z+1, r23
-; CHECK-NEXT: st Z, r22
+; CHECK-NEXT: mov r30, r22
+; CHECK-NEXT: mov r31, r23
+; CHECK-NEXT: std Z+1, r25
+; CHECK-NEXT: st Z, r24
; CHECK-NEXT: ret
store half %x, ptr %p
ret void
@@ -21,8 +21,8 @@ define half @return(ptr %p) nounwind {
; CHECK: ; %bb.0:
; CHECK-NEXT: mov r30, r24
; CHECK-NEXT: mov r31, r25
-; CHECK-NEXT: ld r22, Z
-; CHECK-NEXT: ldd r23, Z+1
+; CHECK-NEXT: ld r24, Z
+; CHECK-NEXT: ldd r25, Z+1
; CHECK-NEXT: ret
%r = load half, ptr %p
ret half %r
@@ -79,8 +79,6 @@ define dso_local void @stored(ptr nocapture %a, double %b) local_unnamed_addr no
; CHECK-NEXT: mov r24, r30
; CHECK-NEXT: mov r25, r31
; CHECK-NEXT: rcall __truncdfhf2
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r30, r16
; CHECK-NEXT: mov r31, r17
; CHECK-NEXT: std Z+1, r25
@@ -108,8 +106,6 @@ define dso_local void @storef(ptr nocapture %a, float %b) local_unnamed_addr nou
; CHECK-NEXT: mov r24, r18
; CHECK-NEXT: mov r25, r19
; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r30, r16
; CHECK-NEXT: mov r31, r17
; CHECK-NEXT: std Z+1, r25
@@ -126,22 +122,14 @@ entry:
define void @test_load_store(ptr %in, ptr %out) nounwind {
; CHECK-LABEL: test_load_store:
; CHECK: ; %bb.0:
-; CHECK-NEXT: push r16
-; CHECK-NEXT: push r17
-; CHECK-NEXT: mov r16, r22
-; CHECK-NEXT: mov r17, r23
; CHECK-NEXT: mov r30, r24
; CHECK-NEXT: mov r31, r25
; CHECK-NEXT: ld r24, Z
; CHECK-NEXT: ldd r25, Z+1
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: mov r30, r16
-; CHECK-NEXT: mov r31, r17
+; CHECK-NEXT: mov r30, r22
+; CHECK-NEXT: mov r31, r23
; CHECK-NEXT: std Z+1, r25
; CHECK-NEXT: st Z, r24
-; CHECK-NEXT: pop r17
-; CHECK-NEXT: pop r16
; CHECK-NEXT: ret
%val = load half, ptr %in
store half %val, ptr %out
@@ -177,8 +165,6 @@ define void @test_bitcast_to_half(ptr %addr, i16 %in) nounwind {
define half @from_bits(i16 %x) nounwind {
; CHECK-LABEL: from_bits:
; CHECK: ; %bb.0:
-; CHECK-NEXT: mov r22, r24
-; CHECK-NEXT: mov r23, r25
; CHECK-NEXT: ret
%res = bitcast i16 %x to half
ret half %res
@@ -187,8 +173,6 @@ define half @from_bits(i16 %x) nounwind {
define i16 @to_bits(half %x) nounwind {
; CHECK-LABEL: to_bits:
; CHECK: ; %bb.0:
-; CHECK-NEXT: mov r24, r22
-; CHECK-NEXT: mov r25, r23
; CHECK-NEXT: ret
%res = bitcast half %x to i16
ret i16 %res
@@ -231,8 +215,6 @@ define void @test_trunc32(float %in, ptr %addr) nounwind {
; CHECK-NEXT: mov r16, r20
; CHECK-NEXT: mov r17, r21
; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r30, r16
; CHECK-NEXT: mov r31, r17
; CHECK-NEXT: std Z+1, r25
@@ -249,8 +231,6 @@ define void @test_trunc64(double %in, ptr %addr) nounwind {
; CHECK-LABEL: test_trunc64:
; CHECK: ; %bb.0:
; CHECK-NEXT: rcall __truncdfhf2
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r30, r16
; CHECK-NEXT: mov r31, r17
; CHECK-NEXT: std Z+1, r25
@@ -281,8 +261,6 @@ define void @test_sitofp_i64(i64 %a, ptr %p) nounwind {
; CHECK: ; %bb.0:
; CHECK-NEXT: rcall __floatdisf
; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r30, r16
; CHECK-NEXT: mov r31, r17
; CHECK-NEXT: std Z+1, r25
@@ -313,8 +291,6 @@ define void @test_uitofp_i64(i64 %a, ptr %p) nounwind {
; CHECK: ; %bb.0:
; CHECK-NEXT: rcall __floatundisf
; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r30, r16
; CHECK-NEXT: mov r31, r17
; CHECK-NEXT: std Z+1, r25
@@ -487,8 +463,6 @@ define void @test_trunc32_vec4(<4 x float> %a, ptr %p) nounwind {
; CHECK-NEXT: mov r4, r18
; CHECK-NEXT: mov r5, r19
; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r30, r8
; CHECK-NEXT: mov r31, r9
; CHECK-NEXT: std Z+7, r25
@@ -498,8 +472,6 @@ define void @test_trunc32_vec4(<4 x float> %a, ptr %p) nounwind {
; CHECK-NEXT: mov r24, r6
; CHECK-NEXT: mov r25, r7
; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r30, r8
; CHECK-NEXT: mov r31, r9
; CHECK-NEXT: std Z+5, r25
@@ -509,8 +481,6 @@ define void @test_trunc32_vec4(<4 x float> %a, ptr %p) nounwind {
; CHECK-NEXT: mov r24, r16
; CHECK-NEXT: mov r25, r17
; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r30, r8
; CHECK-NEXT: mov r31, r9
; CHECK-NEXT: std Z+3, r25
@@ -520,8 +490,6 @@ define void @test_trunc32_vec4(<4 x float> %a, ptr %p) nounwind {
; CHECK-NEXT: mov r24, r12
; CHECK-NEXT: mov r25, r13
; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r30, r8
; CHECK-NEXT: mov r31, r9
; CHECK-NEXT: std Z+1, r25
@@ -554,8 +522,6 @@ define void @test_trunc64_vec4(<4 x double> %a, ptr %p) nounwind {
; CHECK-NEXT: ldd r24, Y+37
; CHECK-NEXT: ldd r25, Y+38
; CHECK-NEXT: rcall __truncdfhf2
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: ldd r18, Y+39
; CHECK-NEXT: ldd r19, Y+40
; CHECK-NEXT: mov r30, r18
@@ -573,8 +539,6 @@ define void @test_trunc64_vec4(<4 x double> %a, ptr %p) nounwind {
; CHECK-NEXT: ldd r24, Y+29
; CHECK-NEXT: ldd r25, Y+30
; CHECK-NEXT: rcall __truncdfhf2
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r30, r16
; CHECK-NEXT: mov r31, r17
; CHECK-NEXT: std Z+5, r25
@@ -588,8 +552,6 @@ define void @test_trunc64_vec4(<4 x double> %a, ptr %p) nounwind {
; CHECK-NEXT: ldd r24, Y+21
; CHECK-NEXT: ldd r25, Y+22
; CHECK-NEXT: rcall __truncdfhf2
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r30, r16
; CHECK-NEXT: mov r31, r17
; CHECK-NEXT: std Z+3, r25
@@ -603,8 +565,6 @@ define void @test_trunc64_vec4(<4 x double> %a, ptr %p) nounwind {
; CHECK-NEXT: ldd r24, Y+13
; CHECK-NEXT: ldd r25, Y+14
; CHECK-NEXT: rcall __truncdfhf2
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r30, r16
; CHECK-NEXT: mov r31, r17
; CHECK-NEXT: std Z+1, r25
@@ -622,51 +582,47 @@ define void @test_trunc64_vec4(<4 x double> %a, ptr %p) nounwind {
define float @test_sitofp_fadd_i32(i32 %a, ptr %b) nounwind {
; CHECK-LABEL: test_sitofp_fadd_i32:
; CHECK: ; %bb.0:
-; CHECK-NEXT: push r10
-; CHECK-NEXT: push r11
; CHECK-NEXT: push r12
; CHECK-NEXT: push r13
; CHECK-NEXT: push r14
; CHECK-NEXT: push r15
; CHECK-NEXT: push r16
; CHECK-NEXT: push r17
-; CHECK-NEXT: mov r16, r24
-; CHECK-NEXT: mov r17, r25
-; CHECK-NEXT: mov r14, r22
-; CHECK-NEXT: mov r15, r23
-; CHECK-NEXT: mov r30, r20
-; CHECK-NEXT: mov r31, r21
+; CHECK-NEXT: mov r16, r20
+; CHECK-NEXT: mov r17, r21
+; CHECK-NEXT: rcall __floatsisf
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r14, r24
+; CHECK-NEXT: mov r15, r25
+; CHECK-NEXT: mov r30, r16
+; CHECK-NEXT: mov r31, r17
; CHECK-NEXT: ld r24, Z
; CHECK-NEXT: ldd r25, Z+1
; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: mov r12, r22
-; CHECK-NEXT: mov r13, r23
-; CHECK-NEXT: mov r10, r24
-; CHECK-NEXT: mov r11, r25
-; CHECK-NEXT: mov r22, r14
-; CHECK-NEXT: mov r23, r15
-; CHECK-NEXT: mov r24, r16
-; CHECK-NEXT: mov r25, r17
-; CHECK-NEXT: rcall __floatsisf
-; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r16, r22
+; CHECK-NEXT: mov r17, r23
+; CHECK-NEXT: mov r12, r24
+; CHECK-NEXT: mov r13, r25
+; CHECK-NEXT: mov r24, r14
+; CHECK-NEXT: mov r25, r15
; CHECK-NEXT: rcall __extendhfsf2
; CHECK-NEXT: mov r18, r22
; CHECK-NEXT: mov r19, r23
; CHECK-NEXT: mov r20, r24
; CHECK-NEXT: mov r21, r25
-; CHECK-NEXT: mov r22, r12
-; CHECK-NEXT: mov r23, r13
-; CHECK-NEXT: mov r24, r10
-; CHECK-NEXT: mov r25, r11
+; CHECK-NEXT: mov r22, r16
+; CHECK-NEXT: mov r23, r17
+; CHECK-NEXT: mov r24, r12
+; CHECK-NEXT: mov r25, r13
; CHECK-NEXT: rcall __addsf3
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: rcall __extendhfsf2
; CHECK-NEXT: pop r17
; CHECK-NEXT: pop r16
; CHECK-NEXT: pop r15
; CHECK-NEXT: pop r14
; CHECK-NEXT: pop r13
; CHECK-NEXT: pop r12
-; CHECK-NEXT: pop r11
-; CHECK-NEXT: pop r10
; CHECK-NEXT: ret
%tmp0 = load half, ptr %b
%tmp1 = sitofp i32 %a to half
@@ -680,8 +636,6 @@ define half @PR40273(half) nounwind {
; CHECK: ; %bb.0:
; CHECK-NEXT: push r16
; CHECK-NEXT: push r17
-; CHECK-NEXT: mov r24, r22
-; CHECK-NEXT: mov r25, r23
; CHECK-NEXT: rcall __extendhfsf2
; CHECK-NEXT: ldi r16, 0
; CHECK-NEXT: ldi r17, 0
@@ -691,20 +645,13 @@ define half @PR40273(half) nounwind {
; CHECK-NEXT: mov r21, r17
; CHECK-NEXT: rcall __nesf2
; CHECK-NEXT: cpi r24, 0
-; CHECK-NEXT: brne .LBB24_2
+; CHECK-NEXT: breq .LBB24_2
; CHECK-NEXT: ; %bb.1:
+; CHECK-NEXT: ldi r16, 0
+; CHECK-NEXT: ldi r17, 60
+; CHECK-NEXT: .LBB24_2:
; CHECK-NEXT: mov r24, r16
; CHECK-NEXT: mov r25, r17
-; CHECK-NEXT: rjmp .LBB24_3
-; CHECK-NEXT: .LBB24_2:
-; CHECK-NEXT: ldi r24, 128
-; CHECK-NEXT: ldi r25, 63
-; CHECK-NEXT: .LBB24_3:
-; CHECK-NEXT: mov r22, r16
-; CHECK-NEXT: mov r23, r17
-; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: mov r22, r24
-; CHECK-NEXT: mov r23, r25
; CHECK-NEXT: pop r17
; CHECK-NEXT: pop r16
; CHECK-NEXT: ret
@@ -716,9 +663,7 @@ define half @PR40273(half) nounwind {
define half @fabs(half %x) nounwind {
; CHECK-LABEL: fabs:
; CHECK: ; %bb.0:
-; CHECK-NEXT: andi r23, 127
-; CHECK-NEXT: ldi r24, 0
-; CHECK-NEXT: ldi r25, 0
+; CHECK-NEXT: andi r25, 127
; CHECK-NEXT: ret
%a = call half @llvm.fabs.f16(half %x)
ret half %a
@@ -727,23 +672,11 @@ define half @fabs(half %x) nounwind {
define half @fcopysign(half %x, half %y) nounwind {
; CHECK-LABEL: fcopysign:
; CHECK: ; %bb.0:
-; CHECK-NEXT: push r16
-; CHECK-NEXT: push r17
-; CHECK-NEXT: mov r16, r18
-; CHECK-NEXT: mov r17, r19
-; CHECK-NEXT: mov r24, r22
-; CHECK-NEXT: mov r25, r23
-; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: andi r16, 0
-; CHECK-NEXT: andi r17, 128
+; CHECK-NEXT: andi r22, 0
+; CHECK-NEXT: andi r23, 128
; CHECK-NEXT: andi r25, 127
-; CHECK-NEXT: or r24, r16
-; CHECK-NEXT: or r25, r17
-; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: mov r22, r24
-; CHECK-NEXT: mov r23, r25
-; CHECK-NEXT: pop r17
-; CHECK-NEXT: pop r16
+; CHECK-NEXT: or r24, r22
+; CHECK-NEXT: or r25, r23
; CHECK-NEXT: ret
%a = call half @llvm.copysign.f16(half %x, half %y)
ret half %a
diff --git a/llvm/test/CodeGen/AVR/llvm.sincos.ll b/llvm/test/CodeGen/AVR/llvm.sincos.ll
index b70b8d34a8a3b..ff01da9fd167b 100644
--- a/llvm/test/CodeGen/AVR/llvm.sincos.ll
+++ b/llvm/test/CodeGen/AVR/llvm.sincos.ll
@@ -11,8 +11,6 @@ define { half, half } @test_sincos_f16(half %a) #0 {
; CHECK-NEXT: push r15
; CHECK-NEXT: push r16
; CHECK-NEXT: push r17
-; CHECK-NEXT: mov r24, r22
-; CHECK-NEXT: mov r25, r23
; CHECK-NEXT: rcall __extendhfsf2
; CHECK-NEXT: mov r16, r22
; CHECK-NEXT: mov r17, r23
@@ -28,10 +26,8 @@ define { half, half } @test_sincos_f16(half %a) #0 {
; CHECK-NEXT: mov r25, r15
; CHECK-NEXT: rcall cos
; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: mov r22, r24
-; CHECK-NEXT: mov r23, r25
-; CHECK-NEXT: mov r18, r12
-; CHECK-NEXT: mov r19, r13
+; CHECK-NEXT: mov r22, r12
+; CHECK-NEXT: mov r23, r13
; CHECK-NEXT: pop r17
; CHECK-NEXT: pop r16
; CHECK-NEXT: pop r15
@@ -46,13 +42,9 @@ define { half, half } @test_sincos_f16(half %a) #0 {
define half @test_sincos_f16_only_use_sin(half %a) #0 {
; CHECK-LABEL: test_sincos_f16_only_use_sin:
; CHECK: ; %bb.0:
-; CHECK-NEXT: mov r24, r22
-; CHECK-NEXT: mov r25, r23
; CHECK-NEXT: rcall __extendhfsf2
; CHECK-NEXT: rcall sin
; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: mov r22, r24
-; CHECK-NEXT: mov r23, r25
; CHECK-NEXT: ret
%result = call { half, half } @llvm.sincos.f16(half %a)
%result.0 = extractvalue { half, half } %result, 0
@@ -62,13 +54,9 @@ define half @test_sincos_f16_only_use_sin(half %a) #0 {
define half @test_sincos_f16_only_use_cos(half %a) #0 {
; CHECK-LABEL: test_sincos_f16_only_use_cos:
; CHECK: ; %bb.0:
-; CHECK-NEXT: mov r24, r22
-; CHECK-NEXT: mov r25, r23
; CHECK-NEXT: rcall __extendhfsf2
; CHECK-NEXT: rcall cos
; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: mov r22, r24
-; CHECK-NEXT: mov r23, r25
; CHECK-NEXT: ret
%result = call { half, half } @llvm.sincos.f16(half %a)
%result.1 = extractvalue { half, half } %result, 1
@@ -90,48 +78,50 @@ define { <2 x half>, <2 x half> } @test_sincos_v2f16(<2 x half> %a) #0 {
; CHECK-NEXT: push r15
; CHECK-NEXT: push r16
; CHECK-NEXT: push r17
-; CHECK-NEXT: mov r10, r22
-; CHECK-NEXT: mov r11, r23
+; CHECK-NEXT: mov r16, r24
+; CHECK-NEXT: mov r17, r25
+; CHECK-NEXT: mov r24, r22
+; CHECK-NEXT: mov r25, r23
; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: mov r16, r22
-; CHECK-NEXT: mov r17, r23
-; CHECK-NEXT: mov r14, r24
-; CHECK-NEXT: mov r15, r25
-; CHECK-NEXT: rcall sin
-; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r14, r22
+; CHECK-NEXT: mov r15, r23
; CHECK-NEXT: mov r12, r24
; CHECK-NEXT: mov r13, r25
-; CHECK-NEXT: mov r24, r10
-; CHECK-NEXT: mov r25, r11
+; CHECK-NEXT: rcall sin
+; CHECK-NEXT: rcall __truncsfhf2
+; CHECK-NEXT: mov r10, r24
+; CHECK-NEXT: mov r11, r25
+; CHECK-NEXT: mov r24, r16
+; CHECK-NEXT: mov r25, r17
; CHECK-NEXT: rcall __extendhfsf2
-; CHECK-NEXT: mov r10, r22
-; CHECK-NEXT: mov r11, r23
+; CHECK-NEXT: mov r16, r22
+; CHECK-NEXT: mov r17, r23
; CHECK-NEXT: mov r8, r24
; CHECK-NEXT: mov r9, r25
-; CHECK-NEXT: rcall cos
+; CHECK-NEXT: rcall sin
; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r6, r24
; CHECK-NEXT: mov r7, r25
-; CHECK-NEXT: mov r22, r10
-; CHECK-NEXT: mov r23, r11
-; CHECK-NEXT: mov r24, r8
-; CHECK-NEXT: mov r25, r9
-; CHECK-NEXT: rcall sin
+; CHECK-NEXT: mov r22, r14
+; CHECK-NEXT: mov r23, r15
+; CHECK-NEXT: mov r24, r12
+; CHECK-NEXT: mov r25, r13
+; CHECK-NEXT: rcall cos
; CHECK-NEXT: rcall __truncsfhf2
-; CHECK-NEXT: mov r10, r24
-; CHECK-NEXT: mov r11, r25
+; CHECK-NEXT: mov r14, r24
+; CHECK-NEXT: mov r15, r25
; CHECK-NEXT: mov r22, r16
; CHECK-NEXT: mov r23, r17
-; CHECK-NEXT: mov r24, r14
-; CHECK-NEXT: mov r25, r15
+; CHECK-NEXT: mov r24, r8
+; CHECK-NEXT: mov r25, r9
; CHECK-NEXT: rcall cos
; CHECK-NEXT: rcall __truncsfhf2
; CHECK-NEXT: mov r18, r10
; CHECK-NEXT: mov r19, r11
-; CHECK-NEXT: mov r20, r12
-; CHECK-NEXT: mov r21, r13
-; CHECK-NEXT: mov r22, r6
-; CHECK-NEXT: mov r23, r7
+; CHECK-NEXT: mov r20, r6
+; CHECK-NEXT: mov r21, r7
+; CHECK-NEXT: mov r22, r14
+; CHECK-NEXT: mov r23, r15
; CHECK-NEXT: pop r17
; CHECK-NEXT: pop r16
; CHECK-NEXT: pop r15
More information about the llvm-commits
mailing list