-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Implement SoftPromoteHalf for FFREXP. #74076
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
Conversation
@llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-llvm-selectiondag Author: Harald van Dijk (hvdijk) Changes
Patch is 43.69 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74076.diff 4 Files Affected:
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 630aa4a07d7b946..c4605a6b9598a9c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -2774,6 +2774,8 @@ void DAGTypeLegalizer::SoftPromoteHalfResult(SDNode *N, unsigned ResNo) {
case ISD::FPOWI:
case ISD::FLDEXP: R = SoftPromoteHalfRes_ExpOp(N); break;
+ case ISD::FFREXP: R = SoftPromoteHalfRes_FFREXP(N); break;
+
case ISD::LOAD: R = SoftPromoteHalfRes_LOAD(N); break;
case ISD::SELECT: R = SoftPromoteHalfRes_SELECT(N); break;
case ISD::SELECT_CC: R = SoftPromoteHalfRes_SELECT_CC(N); break;
@@ -2902,6 +2904,24 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ExpOp(SDNode *N) {
return DAG.getNode(GetPromotionOpcode(NVT, OVT), dl, MVT::i16, Res);
}
+SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FFREXP(SDNode *N) {
+ EVT OVT = N->getValueType(0);
+ EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
+ SDValue Op = GetSoftPromotedHalf(N->getOperand(0));
+ SDLoc dl(N);
+
+ // Promote to the larger FP type.
+ Op = DAG.getNode(GetPromotionOpcode(OVT, NVT), dl, NVT, Op);
+
+ SDValue Res = DAG.getNode(N->getOpcode(), dl,
+ DAG.getVTList(NVT, N->getValueType(1)), Op);
+
+ ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
+
+ // Convert back to FP16 as an integer.
+ return DAG.getNode(GetPromotionOpcode(NVT, OVT), dl, MVT::i16, Res);
+}
+
SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(SDNode *N) {
EVT RVT = N->getValueType(0);
EVT SVT = N->getOperand(0).getValueType();
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index e9bd54089d0627e..9d5931b44ac67cc 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -738,6 +738,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
SDValue SoftPromoteHalfRes_FCOPYSIGN(SDNode *N);
SDValue SoftPromoteHalfRes_FMAD(SDNode *N);
SDValue SoftPromoteHalfRes_ExpOp(SDNode *N);
+ SDValue SoftPromoteHalfRes_FFREXP(SDNode *N);
SDValue SoftPromoteHalfRes_FP_ROUND(SDNode *N);
SDValue SoftPromoteHalfRes_LOAD(SDNode *N);
SDValue SoftPromoteHalfRes_SELECT(SDNode *N);
diff --git a/llvm/test/CodeGen/RISCV/llvm.frexp.ll b/llvm/test/CodeGen/RISCV/llvm.frexp.ll
index f8a8cfc60f14d69..94b9444dfaf8c5b 100644
--- a/llvm/test/CodeGen/RISCV/llvm.frexp.ll
+++ b/llvm/test/CodeGen/RISCV/llvm.frexp.ll
@@ -18,24 +18,279 @@
; TODO: FIXMEs are copied blindly across from the X86 version of this test.
-; FIXME
-; define { half, i32 } @test_frexp_f16_i32(half %a) nounwind {
-; %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
-; ret { half, i32 } %result
-; }
+define { half, i32 } @test_frexp_f16_i32(half %a) nounwind {
+; RV32IFD-LABEL: test_frexp_f16_i32:
+; RV32IFD: # %bb.0:
+; RV32IFD-NEXT: addi sp, sp, -16
+; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IFD-NEXT: call __extendhfsf2@plt
+; RV32IFD-NEXT: addi a0, sp, 8
+; RV32IFD-NEXT: call frexpf@plt
+; RV32IFD-NEXT: call __truncsfhf2@plt
+; RV32IFD-NEXT: fmv.x.w a1, fa0
+; RV32IFD-NEXT: lw a0, 8(sp)
+; RV32IFD-NEXT: lui a2, 1048560
+; RV32IFD-NEXT: or a1, a1, a2
+; RV32IFD-NEXT: fmv.w.x fa0, a1
+; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IFD-NEXT: addi sp, sp, 16
+; RV32IFD-NEXT: ret
+;
+; RV64IFD-LABEL: test_frexp_f16_i32:
+; RV64IFD: # %bb.0:
+; RV64IFD-NEXT: addi sp, sp, -16
+; RV64IFD-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64IFD-NEXT: call __extendhfsf2@plt
+; RV64IFD-NEXT: mv a0, sp
+; RV64IFD-NEXT: call frexpf@plt
+; RV64IFD-NEXT: call __truncsfhf2@plt
+; RV64IFD-NEXT: fmv.x.w a1, fa0
+; RV64IFD-NEXT: ld a0, 0(sp)
+; RV64IFD-NEXT: lui a2, 1048560
+; RV64IFD-NEXT: or a1, a1, a2
+; RV64IFD-NEXT: fmv.w.x fa0, a1
+; RV64IFD-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64IFD-NEXT: addi sp, sp, 16
+; RV64IFD-NEXT: ret
+;
+; RV32IZFINXZDINX-LABEL: test_frexp_f16_i32:
+; RV32IZFINXZDINX: # %bb.0:
+; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
+; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT: call __extendhfsf2@plt
+; RV32IZFINXZDINX-NEXT: addi a1, sp, 8
+; RV32IZFINXZDINX-NEXT: call frexpf@plt
+; RV32IZFINXZDINX-NEXT: call __truncsfhf2@plt
+; RV32IZFINXZDINX-NEXT: lw a1, 8(sp)
+; RV32IZFINXZDINX-NEXT: lui a2, 1048560
+; RV32IZFINXZDINX-NEXT: or a0, a0, a2
+; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
+; RV32IZFINXZDINX-NEXT: ret
+;
+; RV64IZFINXZDINX-LABEL: test_frexp_f16_i32:
+; RV64IZFINXZDINX: # %bb.0:
+; RV64IZFINXZDINX-NEXT: addi sp, sp, -16
+; RV64IZFINXZDINX-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64IZFINXZDINX-NEXT: call __extendhfsf2@plt
+; RV64IZFINXZDINX-NEXT: mv a1, sp
+; RV64IZFINXZDINX-NEXT: call frexpf@plt
+; RV64IZFINXZDINX-NEXT: call __truncsfhf2@plt
+; RV64IZFINXZDINX-NEXT: ld a1, 0(sp)
+; RV64IZFINXZDINX-NEXT: lui a2, 1048560
+; RV64IZFINXZDINX-NEXT: or a0, a0, a2
+; RV64IZFINXZDINX-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64IZFINXZDINX-NEXT: addi sp, sp, 16
+; RV64IZFINXZDINX-NEXT: ret
+;
+; RV32I-LABEL: test_frexp_f16_i32:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi sp, sp, -16
+; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT: slli a0, a0, 16
+; RV32I-NEXT: srli a0, a0, 16
+; RV32I-NEXT: call __extendhfsf2@plt
+; RV32I-NEXT: addi a1, sp, 8
+; RV32I-NEXT: call frexpf@plt
+; RV32I-NEXT: call __truncsfhf2@plt
+; RV32I-NEXT: lw a1, 8(sp)
+; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: test_frexp_f16_i32:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: slli a0, a0, 48
+; RV64I-NEXT: srli a0, a0, 48
+; RV64I-NEXT: call __extendhfsf2@plt
+; RV64I-NEXT: addi a1, sp, 4
+; RV64I-NEXT: call frexpf@plt
+; RV64I-NEXT: call __truncsfhf2@plt
+; RV64I-NEXT: lw a1, 4(sp)
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+ %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
+ ret { half, i32 } %result
+}
-; define half @test_frexp_f16_i32_only_use_fract(half %a) nounwind {
-; %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
-; %result.0 = extractvalue { half, i32 } %result, 0
-; ret half %result.0
-; }
+define half @test_frexp_f16_i32_only_use_fract(half %a) nounwind {
+; RV32IFD-LABEL: test_frexp_f16_i32_only_use_fract:
+; RV32IFD: # %bb.0:
+; RV32IFD-NEXT: addi sp, sp, -16
+; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IFD-NEXT: call __extendhfsf2@plt
+; RV32IFD-NEXT: addi a0, sp, 8
+; RV32IFD-NEXT: call frexpf@plt
+; RV32IFD-NEXT: call __truncsfhf2@plt
+; RV32IFD-NEXT: fmv.x.w a0, fa0
+; RV32IFD-NEXT: lui a1, 1048560
+; RV32IFD-NEXT: or a0, a0, a1
+; RV32IFD-NEXT: fmv.w.x fa0, a0
+; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IFD-NEXT: addi sp, sp, 16
+; RV32IFD-NEXT: ret
+;
+; RV64IFD-LABEL: test_frexp_f16_i32_only_use_fract:
+; RV64IFD: # %bb.0:
+; RV64IFD-NEXT: addi sp, sp, -16
+; RV64IFD-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64IFD-NEXT: call __extendhfsf2@plt
+; RV64IFD-NEXT: mv a0, sp
+; RV64IFD-NEXT: call frexpf@plt
+; RV64IFD-NEXT: call __truncsfhf2@plt
+; RV64IFD-NEXT: fmv.x.w a0, fa0
+; RV64IFD-NEXT: lui a1, 1048560
+; RV64IFD-NEXT: or a0, a0, a1
+; RV64IFD-NEXT: fmv.w.x fa0, a0
+; RV64IFD-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64IFD-NEXT: addi sp, sp, 16
+; RV64IFD-NEXT: ret
+;
+; RV32IZFINXZDINX-LABEL: test_frexp_f16_i32_only_use_fract:
+; RV32IZFINXZDINX: # %bb.0:
+; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
+; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT: call __extendhfsf2@plt
+; RV32IZFINXZDINX-NEXT: addi a1, sp, 8
+; RV32IZFINXZDINX-NEXT: call frexpf@plt
+; RV32IZFINXZDINX-NEXT: call __truncsfhf2@plt
+; RV32IZFINXZDINX-NEXT: lui a1, 1048560
+; RV32IZFINXZDINX-NEXT: or a0, a0, a1
+; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
+; RV32IZFINXZDINX-NEXT: ret
+;
+; RV64IZFINXZDINX-LABEL: test_frexp_f16_i32_only_use_fract:
+; RV64IZFINXZDINX: # %bb.0:
+; RV64IZFINXZDINX-NEXT: addi sp, sp, -16
+; RV64IZFINXZDINX-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64IZFINXZDINX-NEXT: call __extendhfsf2@plt
+; RV64IZFINXZDINX-NEXT: mv a1, sp
+; RV64IZFINXZDINX-NEXT: call frexpf@plt
+; RV64IZFINXZDINX-NEXT: call __truncsfhf2@plt
+; RV64IZFINXZDINX-NEXT: lui a1, 1048560
+; RV64IZFINXZDINX-NEXT: or a0, a0, a1
+; RV64IZFINXZDINX-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64IZFINXZDINX-NEXT: addi sp, sp, 16
+; RV64IZFINXZDINX-NEXT: ret
+;
+; RV32I-LABEL: test_frexp_f16_i32_only_use_fract:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi sp, sp, -16
+; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT: slli a0, a0, 16
+; RV32I-NEXT: srli a0, a0, 16
+; RV32I-NEXT: call __extendhfsf2@plt
+; RV32I-NEXT: addi a1, sp, 8
+; RV32I-NEXT: call frexpf@plt
+; RV32I-NEXT: call __truncsfhf2@plt
+; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: test_frexp_f16_i32_only_use_fract:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: slli a0, a0, 48
+; RV64I-NEXT: srli a0, a0, 48
+; RV64I-NEXT: call __extendhfsf2@plt
+; RV64I-NEXT: addi a1, sp, 4
+; RV64I-NEXT: call frexpf@plt
+; RV64I-NEXT: call __truncsfhf2@plt
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+ %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
+ %result.0 = extractvalue { half, i32 } %result, 0
+ ret half %result.0
+}
-; define i32 @test_frexp_f16_i32_only_use_exp(half %a) nounwind {
-; %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
-; %result.0 = extractvalue { half, i32 } %result, 1
-; ret i32 %result.0
-; }
+define i32 @test_frexp_f16_i32_only_use_exp(half %a) nounwind {
+; RV32IFD-LABEL: test_frexp_f16_i32_only_use_exp:
+; RV32IFD: # %bb.0:
+; RV32IFD-NEXT: addi sp, sp, -16
+; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IFD-NEXT: call __extendhfsf2@plt
+; RV32IFD-NEXT: addi a0, sp, 8
+; RV32IFD-NEXT: call frexpf@plt
+; RV32IFD-NEXT: lw a0, 8(sp)
+; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IFD-NEXT: addi sp, sp, 16
+; RV32IFD-NEXT: ret
+;
+; RV64IFD-LABEL: test_frexp_f16_i32_only_use_exp:
+; RV64IFD: # %bb.0:
+; RV64IFD-NEXT: addi sp, sp, -16
+; RV64IFD-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64IFD-NEXT: call __extendhfsf2@plt
+; RV64IFD-NEXT: mv a0, sp
+; RV64IFD-NEXT: call frexpf@plt
+; RV64IFD-NEXT: ld a0, 0(sp)
+; RV64IFD-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64IFD-NEXT: addi sp, sp, 16
+; RV64IFD-NEXT: ret
+;
+; RV32IZFINXZDINX-LABEL: test_frexp_f16_i32_only_use_exp:
+; RV32IZFINXZDINX: # %bb.0:
+; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
+; RV32IZFINXZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT: call __extendhfsf2@plt
+; RV32IZFINXZDINX-NEXT: addi a1, sp, 8
+; RV32IZFINXZDINX-NEXT: call frexpf@plt
+; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
+; RV32IZFINXZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
+; RV32IZFINXZDINX-NEXT: ret
+;
+; RV64IZFINXZDINX-LABEL: test_frexp_f16_i32_only_use_exp:
+; RV64IZFINXZDINX: # %bb.0:
+; RV64IZFINXZDINX-NEXT: addi sp, sp, -16
+; RV64IZFINXZDINX-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64IZFINXZDINX-NEXT: call __extendhfsf2@plt
+; RV64IZFINXZDINX-NEXT: mv a1, sp
+; RV64IZFINXZDINX-NEXT: call frexpf@plt
+; RV64IZFINXZDINX-NEXT: ld a0, 0(sp)
+; RV64IZFINXZDINX-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64IZFINXZDINX-NEXT: addi sp, sp, 16
+; RV64IZFINXZDINX-NEXT: ret
+;
+; RV32I-LABEL: test_frexp_f16_i32_only_use_exp:
+; RV32I: # %bb.0:
+; RV32I-NEXT: addi sp, sp, -16
+; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT: slli a0, a0, 16
+; RV32I-NEXT: srli a0, a0, 16
+; RV32I-NEXT: call __extendhfsf2@plt
+; RV32I-NEXT: addi a1, sp, 8
+; RV32I-NEXT: call frexpf@plt
+; RV32I-NEXT: lw a0, 8(sp)
+; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: test_frexp_f16_i32_only_use_exp:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: slli a0, a0, 48
+; RV64I-NEXT: srli a0, a0, 48
+; RV64I-NEXT: call __extendhfsf2@plt
+; RV64I-NEXT: addi a1, sp, 4
+; RV64I-NEXT: call frexpf@plt
+; RV64I-NEXT: lw a0, 4(sp)
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+ %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
+ %result.0 = extractvalue { half, i32 } %result, 1
+ ret i32 %result.0
+}
+; FIXME
; define { <2 x half>, <2 x i32> } @test_frexp_v2f16_v2i32(<2 x half> %a) nounwind {
; %result = call { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half> %a)
; ret { <2 x half>, <2 x i32> } %result
diff --git a/llvm/test/CodeGen/X86/llvm.frexp.ll b/llvm/test/CodeGen/X86/llvm.frexp.ll
index bd0a1dce6946c64..d6038cebd45822b 100644
--- a/llvm/test/CodeGen/X86/llvm.frexp.ll
+++ b/llvm/test/CodeGen/X86/llvm.frexp.ll
@@ -2,24 +2,241 @@
; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck -check-prefixes=X64 %s
; RUN: llc -mtriple=i386-pc-win32 < %s | FileCheck -check-prefix=WIN32 %s
-; FIXME
-; define { half, i32 } @test_frexp_f16_i32(half %a) {
-; %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
-; ret { half, i32 } %result
-; }
+define { half, i32 } @test_frexp_f16_i32(half %a) {
+; X64-LABEL: test_frexp_f16_i32:
+; X64: # %bb.0:
+; X64-NEXT: subq $24, %rsp
+; X64-NEXT: .cfi_def_cfa_offset 32
+; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
+; X64-NEXT: callq __extendhfsf2@PLT
+; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT: callq __truncsfhf2@PLT
+; X64-NEXT: pextrw $0, %xmm0, %ecx
+; X64-NEXT: movl %ecx, %eax
+; X64-NEXT: andl $31744, %eax # imm = 0x7C00
+; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload
+; X64-NEXT: pextrw $0, %xmm0, %edx
+; X64-NEXT: movl %edx, %esi
+; X64-NEXT: andl $32767, %esi # imm = 0x7FFF
+; X64-NEXT: cmpl $1024, %esi # imm = 0x400
+; X64-NEXT: cmovael %edx, %ecx
+; X64-NEXT: cmovael %esi, %eax
+; X64-NEXT: shrl $10, %eax
+; X64-NEXT: leal -12(%rax), %edi
+; X64-NEXT: cmpl $1024, %esi # imm = 0x400
+; X64-NEXT: cmovael %eax, %edi
+; X64-NEXT: addl $-14, %edi
+; X64-NEXT: andl $-31745, %ecx # imm = 0x83FF
+; X64-NEXT: orl $14336, %ecx # imm = 0x3800
+; X64-NEXT: addl $-31744, %esi # imm = 0x8400
+; X64-NEXT: movzwl %si, %esi
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpl $33792, %esi # imm = 0x8400
+; X64-NEXT: cmoval %edi, %eax
+; X64-NEXT: cmovbel %edx, %ecx
+; X64-NEXT: pinsrw $0, %ecx, %xmm0
+; X64-NEXT: addq $24, %rsp
+; X64-NEXT: .cfi_def_cfa_offset 8
+; X64-NEXT: retq
+;
+; WIN32-LABEL: test_frexp_f16_i32:
+; WIN32: # %bb.0:
+; WIN32-NEXT: pushl %esi
+; WIN32-NEXT: subl $16, %esp
+; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT: movl %eax, (%esp)
+; WIN32-NEXT: calll ___gnu_h2f_ieee
+; WIN32-NEXT: fld %st(0)
+; WIN32-NEXT: fmuls __real@4c000000
+; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT: fsts {{[0-9]+}}(%esp)
+; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; WIN32-NEXT: movl %edx, %ecx
+; WIN32-NEXT: andl $2147483647, %ecx # imm = 0x7FFFFFFF
+; WIN32-NEXT: cmpl $8388608, %ecx # imm = 0x800000
+; WIN32-NEXT: jb LBB0_1
+; WIN32-NEXT: # %bb.2:
+; WIN32-NEXT: movl %ecx, %eax
+; WIN32-NEXT: jmp LBB0_3
+; WIN32-NEXT: LBB0_1:
+; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; WIN32-NEXT: movl %edx, %eax
+; WIN32-NEXT: andl $2139095040, %eax # imm = 0x7F800000
+; WIN32-NEXT: LBB0_3:
+; WIN32-NEXT: shrl $23, %eax
+; WIN32-NEXT: cmpl $8388608, %ecx # imm = 0x800000
+; WIN32-NEXT: jae LBB0_5
+; WIN32-NEXT: # %bb.4:
+; WIN32-NEXT: addl $-25, %eax
+; WIN32-NEXT: LBB0_5:
+; WIN32-NEXT: andl $-2139095041, %edx # imm = 0x807FFFFF
+; WIN32-NEXT: orl $1056964608, %edx # imm = 0x3F000000
+; WIN32-NEXT: movl %edx, {{[0-9]+}}(%esp)
+; WIN32-NEXT: addl $-126, %eax
+; WIN32-NEXT: addl $-2139095040, %ecx # imm = 0x80800000
+; WIN32-NEXT: flds {{[0-9]+}}(%esp)
+; WIN32-NEXT: xorl %esi, %esi
+; WIN32-NEXT: cmpl $-2139095040, %ecx # imm = 0x80800000
+; WIN32-NEXT: jbe LBB0_7
+; WIN32-NEXT: # %bb.6:
+; WIN32-NEXT: fstp %st(1)
+; WIN32-NEXT: fldz
+; WIN32-NEXT: LBB0_7:
+; WIN32-NEXT: fstp %st(0)
+; WIN32-NEXT: fstps (%esp)
+; WIN32-NEXT: jbe LBB0_9
+; WIN32-NEXT: # %bb.8:
+; WIN32-NEXT: movl %eax, %esi
+; WIN32-NEXT: LBB0_9:
+; WIN32-NEXT: calll ___gnu_f2h_ieee
+; WIN32-NEXT: movl %esi, %edx
+; WIN32-NEXT: addl $16, %esp
+; WIN32-NEXT: popl %esi
+; WIN32-NEXT: retl
+ %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
+ ret { half, i32 } %result
+}
-; define half @test_frexp_f16_i32_only_use_fract(half %a) {
-; %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
-; %result.0 = extractvalue { half, i32 } %result, 0
-; ret half %result.0
-; }
+define half @test_frexp_f16_i32_only_use_fract(half %a) {
+; X64-LABEL: test_frexp_f16_i32_only_use_fract:
+; X64: # %bb.0:
+; X64-NEXT: subq $24, %rsp
+; X64-NEXT: .cfi_def_cfa_offset 32
+; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
+; X64-NEXT: callq __extendhfsf2@PLT
+; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT: callq __truncsfhf2@PLT
+; X64-NEXT: pextrw $0, %xmm0, %eax
+; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload
+; X64-NEXT: pextrw $0, %xmm0, %ecx
+; X64-NEXT: movl %ecx, %edx
+; X64-NEXT: andl $32767, %edx # imm = 0x7FFF
+; X64-NEXT: cmpl $1024, %edx # imm = 0x400
+; X64-NEXT: cmovael %ecx, %eax
+; X64-NEXT: andl $-31745, %eax # imm = 0x83FF
+; X64-NEXT: orl $14336, %eax # imm = 0x3800
+; X64-NEXT: addl $-31744, %edx # imm = 0x8400
+; X64-NEXT: movzwl %dx, %edx
+; X64-NEXT: cmpl $33792, %edx # imm = 0x8400
+; X64-NEXT: cmovbel %ecx, %eax
+; X64-NEXT: pinsrw $0, %eax, %xmm0
+; X64-NEXT: addq $24, %rsp
+; X64-NEXT: .cfi_def_cfa_offset 8
+; X64-NEXT: retq
+;
+; WIN32-LABEL: test_frexp_f16_i32_only_use_fract:
+; WIN32: # %bb.0:
+; WIN32-NEXT: subl $16, %esp
+; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT: movl %eax, (%esp)
+; WIN32-NEXT: calll ___gnu_h2f_ieee
+; WIN32-NEXT: fsts {{[0-9]+}}(%esp)
+; WIN32-NEXT: fld %st(0)
+; WIN32-NEXT: fmuls __real@4c000000
+; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; WIN32-NEXT: movl %ecx, %eax
+; WIN32-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF
+; WIN32-NEXT: cmpl $8388608, %eax # imm = 0x800000
+; WIN32-NEXT: jae LBB1_2
+; WIN32-NEXT: # %bb.1:
+; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; WIN32-NEXT: LBB1_2:
+; WIN32-NEXT: andl $-2139095041, %ecx # imm = 0x807FFFFF
+; WIN32-NEXT: orl $1056964608, %ecx # imm = 0x3F000000
+; WIN32-NEXT: movl %ecx, {{[0-9]+}}(%esp)
+; WIN32-NEXT: addl $-2139095040, %eax # imm = 0x80800000
+; WIN32-NEXT: flds {{[0-9]+}}(%esp)
+; WIN32-NEXT: cmpl $-2139095040, %eax # imm = 0x80800000
+; WIN32-NEXT: jbe LBB1_4
+; WIN32-NEXT: # %bb.3:
+; WIN32-NEXT: fstp %st(1)
+; WIN32-NEXT: fldz
+; WIN32-NEXT: LBB1_4:
+; WIN32-NEXT: fstp %st(0)
+; WIN32-NEXT: fstps (%esp)
+; WIN32-NEXT: calll ___gnu_f2h_ieee
+; WIN32-NEX...
[truncated]
|
You can test this locally with the following command:git-clang-format --diff da86d4a8c956f0fcee21444eb6de9f05d39d6574 5db539d7fed0eae3268f82bc47e12fd76c5e03ea -- llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h View the diff from clang-format here.diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index c4605a6b95..ccbbcf202a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -2774,7 +2774,9 @@ void DAGTypeLegalizer::SoftPromoteHalfResult(SDNode *N, unsigned ResNo) {
case ISD::FPOWI:
case ISD::FLDEXP: R = SoftPromoteHalfRes_ExpOp(N); break;
- case ISD::FFREXP: R = SoftPromoteHalfRes_FFREXP(N); break;
+ case ISD::FFREXP:
+ R = SoftPromoteHalfRes_FFREXP(N);
+ break;
case ISD::LOAD: R = SoftPromoteHalfRes_LOAD(N); break;
case ISD::SELECT: R = SoftPromoteHalfRes_SELECT(N); break;
|
This whole file is not |
llvm/test/CodeGen/RISCV/llvm.frexp.ll
andllvm/test/CodeGen/X86/llvm.frexp.ll
contain a number of disabled tests for unimplemented functionality. This implements one missing part of it.