[llvm] e8ed6e3 - DAG: Implement soften float for ffrexp

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 5 18:42:32 PDT 2023


Author: Matt Arsenault
Date: 2023-07-05T21:42:27-04:00
New Revision: e8ed6e35bdea7f8e54f0018309bc3d0181f01ab5

URL: https://github.com/llvm/llvm-project/commit/e8ed6e35bdea7f8e54f0018309bc3d0181f01ab5
DIFF: https://github.com/llvm/llvm-project/commit/e8ed6e35bdea7f8e54f0018309bc3d0181f01ab5.diff

LOG: DAG: Implement soften float for ffrexp

Fixes #63661

https://reviews.llvm.org/D154555

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
    llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
    llvm/test/CodeGen/RISCV/llvm.frexp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 219e27debb3d50..ce2388b1ff018d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -114,6 +114,9 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
     case ISD::FPOWI:
     case ISD::FLDEXP:
     case ISD::STRICT_FLDEXP: R = SoftenFloatRes_ExpOp(N); break;
+    case ISD::FFREXP:
+      R = SoftenFloatRes_FFREXP(N);
+      break;
     case ISD::STRICT_FREM:
     case ISD::FREM:        R = SoftenFloatRes_FREM(N); break;
     case ISD::STRICT_FRINT:
@@ -650,6 +653,45 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_ExpOp(SDNode *N) {
   return Tmp.first;
 }
 
+SDValue DAGTypeLegalizer::SoftenFloatRes_FFREXP(SDNode *N) {
+  assert(!N->isStrictFPOpcode() && "strictfp not implemented for frexp");
+  EVT VT0 = N->getValueType(0);
+  EVT VT1 = N->getValueType(1);
+  RTLIB::Libcall LC = RTLIB::getFREXP(VT0);
+
+  if (DAG.getLibInfo().getIntSize() != VT1.getSizeInBits()) {
+    // If the exponent does not match with sizeof(int) a libcall would use the
+    // wrong type for the argument.
+    // TODO: Should be able to handle mismatches.
+    DAG.getContext()->emitError("ffrexp exponent does not match sizeof(int)");
+    return DAG.getUNDEF(N->getValueType(0));
+  }
+
+  EVT NVT0 = TLI.getTypeToTransformTo(*DAG.getContext(), VT0);
+  SDValue StackSlot = DAG.CreateStackTemporary(VT1);
+
+  SDLoc DL(N);
+
+  TargetLowering::MakeLibCallOptions CallOptions;
+  SDValue Ops[2] = {GetSoftenedFloat(N->getOperand(0)), StackSlot};
+  EVT OpsVT[2] = {VT0, StackSlot.getValueType()};
+
+  // TODO: setTypeListBeforeSoften can't properly express multiple return types,
+  // but we only really need to handle the 0th one for softening anyway.
+  CallOptions.setTypeListBeforeSoften({OpsVT}, VT0, true);
+
+  auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LC, NVT0, Ops, CallOptions, DL,
+                                            /*Chain=*/SDValue());
+  int FrameIdx = cast<FrameIndexSDNode>(StackSlot)->getIndex();
+  auto PtrInfo =
+      MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FrameIdx);
+
+  SDValue LoadExp = DAG.getLoad(VT1, DL, Chain, StackSlot, PtrInfo);
+
+  ReplaceValueWith(SDValue(N, 1), LoadExp);
+  return ReturnVal;
+}
+
 SDValue DAGTypeLegalizer::SoftenFloatRes_FREM(SDNode *N) {
   return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                                RTLIB::REM_F32,

diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 1446eecb0ba15f..db8f61eee6062c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -566,6 +566,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   SDValue SoftenFloatRes_FP_ROUND(SDNode *N);
   SDValue SoftenFloatRes_FPOW(SDNode *N);
   SDValue SoftenFloatRes_ExpOp(SDNode *N);
+  SDValue SoftenFloatRes_FFREXP(SDNode *N);
   SDValue SoftenFloatRes_FREEZE(SDNode *N);
   SDValue SoftenFloatRes_FREM(SDNode *N);
   SDValue SoftenFloatRes_FRINT(SDNode *N);

diff  --git a/llvm/test/CodeGen/RISCV/llvm.frexp.ll b/llvm/test/CodeGen/RISCV/llvm.frexp.ll
index 6efbf76e7c8ac6..150e4d15a8bc50 100644
--- a/llvm/test/CodeGen/RISCV/llvm.frexp.ll
+++ b/llvm/test/CodeGen/RISCV/llvm.frexp.ll
@@ -905,23 +905,271 @@ define i32 @test_frexp_f64_i32_only_use_exp(double %a) nounwind {
 ;   ret <2 x i32> %result.1
 ; }
 
-; FIXME: fp128 softening crashes
-; define { fp128, i32 } @test_frexp_f128_i32(fp128 %a) nounwind {
-;   %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a)
-;   ret { fp128, i32 } %result
-; }
+define { fp128, i32 } @test_frexp_f128_i32(fp128 %a) nounwind {
+; RV32IFD-LABEL: test_frexp_f128_i32:
+; RV32IFD:       # %bb.0:
+; RV32IFD-NEXT:    addi sp, sp, -48
+; RV32IFD-NEXT:    sw ra, 44(sp) # 4-byte Folded Spill
+; RV32IFD-NEXT:    sw s0, 40(sp) # 4-byte Folded Spill
+; RV32IFD-NEXT:    lw a3, 0(a1)
+; RV32IFD-NEXT:    lw a2, 4(a1)
+; RV32IFD-NEXT:    lw a4, 8(a1)
+; RV32IFD-NEXT:    lw a1, 12(a1)
+; RV32IFD-NEXT:    mv s0, a0
+; RV32IFD-NEXT:    sw a1, 12(sp)
+; RV32IFD-NEXT:    sw a4, 8(sp)
+; RV32IFD-NEXT:    sw a2, 4(sp)
+; RV32IFD-NEXT:    addi a0, sp, 16
+; RV32IFD-NEXT:    mv a1, sp
+; RV32IFD-NEXT:    addi a2, sp, 36
+; RV32IFD-NEXT:    sw a3, 0(sp)
+; RV32IFD-NEXT:    call frexpl at plt
+; RV32IFD-NEXT:    lw a0, 36(sp)
+; RV32IFD-NEXT:    lw a1, 28(sp)
+; RV32IFD-NEXT:    lw a2, 24(sp)
+; RV32IFD-NEXT:    lw a3, 20(sp)
+; RV32IFD-NEXT:    lw a4, 16(sp)
+; RV32IFD-NEXT:    sw a1, 12(s0)
+; RV32IFD-NEXT:    sw a2, 8(s0)
+; RV32IFD-NEXT:    sw a3, 4(s0)
+; RV32IFD-NEXT:    sw a4, 0(s0)
+; RV32IFD-NEXT:    sw a0, 16(s0)
+; RV32IFD-NEXT:    lw ra, 44(sp) # 4-byte Folded Reload
+; RV32IFD-NEXT:    lw s0, 40(sp) # 4-byte Folded Reload
+; RV32IFD-NEXT:    addi sp, sp, 48
+; RV32IFD-NEXT:    ret
+;
+; RV64IFD-LABEL: test_frexp_f128_i32:
+; RV64IFD:       # %bb.0:
+; RV64IFD-NEXT:    addi sp, sp, -32
+; RV64IFD-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
+; RV64IFD-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
+; RV64IFD-NEXT:    mv a3, a2
+; RV64IFD-NEXT:    mv s0, a0
+; RV64IFD-NEXT:    addi a2, sp, 12
+; RV64IFD-NEXT:    mv a0, a1
+; RV64IFD-NEXT:    mv a1, a3
+; RV64IFD-NEXT:    call frexpl at plt
+; RV64IFD-NEXT:    lw a2, 12(sp)
+; RV64IFD-NEXT:    sd a1, 8(s0)
+; RV64IFD-NEXT:    sd a0, 0(s0)
+; RV64IFD-NEXT:    sw a2, 16(s0)
+; RV64IFD-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
+; RV64IFD-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
+; RV64IFD-NEXT:    addi sp, sp, 32
+; RV64IFD-NEXT:    ret
+;
+; RV32IZFINXZDINX-LABEL: test_frexp_f128_i32:
+; RV32IZFINXZDINX:       # %bb.0:
+; RV32IZFINXZDINX-NEXT:    addi sp, sp, -48
+; RV32IZFINXZDINX-NEXT:    sw ra, 44(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT:    sw s0, 40(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT:    lw a3, 0(a1)
+; RV32IZFINXZDINX-NEXT:    lw a2, 4(a1)
+; RV32IZFINXZDINX-NEXT:    lw a4, 8(a1)
+; RV32IZFINXZDINX-NEXT:    lw a1, 12(a1)
+; RV32IZFINXZDINX-NEXT:    mv s0, a0
+; RV32IZFINXZDINX-NEXT:    sw a1, 12(sp)
+; RV32IZFINXZDINX-NEXT:    sw a4, 8(sp)
+; RV32IZFINXZDINX-NEXT:    sw a2, 4(sp)
+; RV32IZFINXZDINX-NEXT:    addi a0, sp, 16
+; RV32IZFINXZDINX-NEXT:    mv a1, sp
+; RV32IZFINXZDINX-NEXT:    addi a2, sp, 36
+; RV32IZFINXZDINX-NEXT:    sw a3, 0(sp)
+; RV32IZFINXZDINX-NEXT:    call frexpl at plt
+; RV32IZFINXZDINX-NEXT:    lw a0, 36(sp)
+; RV32IZFINXZDINX-NEXT:    lw a1, 28(sp)
+; RV32IZFINXZDINX-NEXT:    lw a2, 24(sp)
+; RV32IZFINXZDINX-NEXT:    lw a3, 20(sp)
+; RV32IZFINXZDINX-NEXT:    lw a4, 16(sp)
+; RV32IZFINXZDINX-NEXT:    sw a1, 12(s0)
+; RV32IZFINXZDINX-NEXT:    sw a2, 8(s0)
+; RV32IZFINXZDINX-NEXT:    sw a3, 4(s0)
+; RV32IZFINXZDINX-NEXT:    sw a4, 0(s0)
+; RV32IZFINXZDINX-NEXT:    sw a0, 16(s0)
+; RV32IZFINXZDINX-NEXT:    lw ra, 44(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT:    lw s0, 40(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT:    addi sp, sp, 48
+; RV32IZFINXZDINX-NEXT:    ret
+;
+; RV64IZFINXZDINX-LABEL: test_frexp_f128_i32:
+; RV64IZFINXZDINX:       # %bb.0:
+; RV64IZFINXZDINX-NEXT:    addi sp, sp, -32
+; RV64IZFINXZDINX-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
+; RV64IZFINXZDINX-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
+; RV64IZFINXZDINX-NEXT:    mv a3, a2
+; RV64IZFINXZDINX-NEXT:    mv s0, a0
+; RV64IZFINXZDINX-NEXT:    addi a2, sp, 12
+; RV64IZFINXZDINX-NEXT:    mv a0, a1
+; RV64IZFINXZDINX-NEXT:    mv a1, a3
+; RV64IZFINXZDINX-NEXT:    call frexpl at plt
+; RV64IZFINXZDINX-NEXT:    lw a2, 12(sp)
+; RV64IZFINXZDINX-NEXT:    sd a1, 8(s0)
+; RV64IZFINXZDINX-NEXT:    sd a0, 0(s0)
+; RV64IZFINXZDINX-NEXT:    sw a2, 16(s0)
+; RV64IZFINXZDINX-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
+; RV64IZFINXZDINX-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
+; RV64IZFINXZDINX-NEXT:    addi sp, sp, 32
+; RV64IZFINXZDINX-NEXT:    ret
+  %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a)
+  ret { fp128, i32 } %result
+}
 
-; define fp128 @test_frexp_f128_i32_only_use_fract(fp128 %a) nounwind {
-;   %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a)
-;   %result.0 = extractvalue { fp128, i32 } %result, 0
-;   ret fp128 %result.0
-; }
+define fp128 @test_frexp_f128_i32_only_use_fract(fp128 %a) nounwind {
+; RV32IFD-LABEL: test_frexp_f128_i32_only_use_fract:
+; RV32IFD:       # %bb.0:
+; RV32IFD-NEXT:    addi sp, sp, -48
+; RV32IFD-NEXT:    sw ra, 44(sp) # 4-byte Folded Spill
+; RV32IFD-NEXT:    sw s0, 40(sp) # 4-byte Folded Spill
+; RV32IFD-NEXT:    lw a3, 0(a1)
+; RV32IFD-NEXT:    lw a2, 4(a1)
+; RV32IFD-NEXT:    lw a4, 8(a1)
+; RV32IFD-NEXT:    lw a1, 12(a1)
+; RV32IFD-NEXT:    mv s0, a0
+; RV32IFD-NEXT:    sw a1, 12(sp)
+; RV32IFD-NEXT:    sw a4, 8(sp)
+; RV32IFD-NEXT:    sw a2, 4(sp)
+; RV32IFD-NEXT:    addi a0, sp, 16
+; RV32IFD-NEXT:    mv a1, sp
+; RV32IFD-NEXT:    addi a2, sp, 36
+; RV32IFD-NEXT:    sw a3, 0(sp)
+; RV32IFD-NEXT:    call frexpl at plt
+; RV32IFD-NEXT:    lw a0, 28(sp)
+; RV32IFD-NEXT:    lw a1, 24(sp)
+; RV32IFD-NEXT:    lw a2, 20(sp)
+; RV32IFD-NEXT:    lw a3, 16(sp)
+; RV32IFD-NEXT:    sw a0, 12(s0)
+; RV32IFD-NEXT:    sw a1, 8(s0)
+; RV32IFD-NEXT:    sw a2, 4(s0)
+; RV32IFD-NEXT:    sw a3, 0(s0)
+; RV32IFD-NEXT:    lw ra, 44(sp) # 4-byte Folded Reload
+; RV32IFD-NEXT:    lw s0, 40(sp) # 4-byte Folded Reload
+; RV32IFD-NEXT:    addi sp, sp, 48
+; RV32IFD-NEXT:    ret
+;
+; RV64IFD-LABEL: test_frexp_f128_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:    addi a2, sp, 4
+; RV64IFD-NEXT:    call frexpl at plt
+; RV64IFD-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64IFD-NEXT:    addi sp, sp, 16
+; RV64IFD-NEXT:    ret
+;
+; RV32IZFINXZDINX-LABEL: test_frexp_f128_i32_only_use_fract:
+; RV32IZFINXZDINX:       # %bb.0:
+; RV32IZFINXZDINX-NEXT:    addi sp, sp, -48
+; RV32IZFINXZDINX-NEXT:    sw ra, 44(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT:    sw s0, 40(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT:    lw a3, 0(a1)
+; RV32IZFINXZDINX-NEXT:    lw a2, 4(a1)
+; RV32IZFINXZDINX-NEXT:    lw a4, 8(a1)
+; RV32IZFINXZDINX-NEXT:    lw a1, 12(a1)
+; RV32IZFINXZDINX-NEXT:    mv s0, a0
+; RV32IZFINXZDINX-NEXT:    sw a1, 12(sp)
+; RV32IZFINXZDINX-NEXT:    sw a4, 8(sp)
+; RV32IZFINXZDINX-NEXT:    sw a2, 4(sp)
+; RV32IZFINXZDINX-NEXT:    addi a0, sp, 16
+; RV32IZFINXZDINX-NEXT:    mv a1, sp
+; RV32IZFINXZDINX-NEXT:    addi a2, sp, 36
+; RV32IZFINXZDINX-NEXT:    sw a3, 0(sp)
+; RV32IZFINXZDINX-NEXT:    call frexpl at plt
+; RV32IZFINXZDINX-NEXT:    lw a0, 28(sp)
+; RV32IZFINXZDINX-NEXT:    lw a1, 24(sp)
+; RV32IZFINXZDINX-NEXT:    lw a2, 20(sp)
+; RV32IZFINXZDINX-NEXT:    lw a3, 16(sp)
+; RV32IZFINXZDINX-NEXT:    sw a0, 12(s0)
+; RV32IZFINXZDINX-NEXT:    sw a1, 8(s0)
+; RV32IZFINXZDINX-NEXT:    sw a2, 4(s0)
+; RV32IZFINXZDINX-NEXT:    sw a3, 0(s0)
+; RV32IZFINXZDINX-NEXT:    lw ra, 44(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT:    lw s0, 40(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT:    addi sp, sp, 48
+; RV32IZFINXZDINX-NEXT:    ret
+;
+; RV64IZFINXZDINX-LABEL: test_frexp_f128_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:    addi a2, sp, 4
+; RV64IZFINXZDINX-NEXT:    call frexpl at plt
+; RV64IZFINXZDINX-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64IZFINXZDINX-NEXT:    addi sp, sp, 16
+; RV64IZFINXZDINX-NEXT:    ret
+  %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a)
+  %result.0 = extractvalue { fp128, i32 } %result, 0
+  ret fp128 %result.0
+}
 
-; define i32 @test_frexp_f128_i32_only_use_exp(fp128 %a) nounwind {
-;   %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a)
-;   %result.0 = extractvalue { fp128, i32 } %result, 1
-;   ret i32 %result.0
-; }
+define i32 @test_frexp_f128_i32_only_use_exp(fp128 %a) nounwind {
+; RV32IFD-LABEL: test_frexp_f128_i32_only_use_exp:
+; RV32IFD:       # %bb.0:
+; RV32IFD-NEXT:    addi sp, sp, -48
+; RV32IFD-NEXT:    sw ra, 44(sp) # 4-byte Folded Spill
+; RV32IFD-NEXT:    lw a3, 0(a0)
+; RV32IFD-NEXT:    lw a1, 4(a0)
+; RV32IFD-NEXT:    lw a2, 8(a0)
+; RV32IFD-NEXT:    lw a0, 12(a0)
+; RV32IFD-NEXT:    sw a0, 20(sp)
+; RV32IFD-NEXT:    sw a2, 16(sp)
+; RV32IFD-NEXT:    sw a1, 12(sp)
+; RV32IFD-NEXT:    addi a0, sp, 24
+; RV32IFD-NEXT:    addi a1, sp, 8
+; RV32IFD-NEXT:    addi a2, sp, 40
+; RV32IFD-NEXT:    sw a3, 8(sp)
+; RV32IFD-NEXT:    call frexpl at plt
+; RV32IFD-NEXT:    lw a0, 40(sp)
+; RV32IFD-NEXT:    lw ra, 44(sp) # 4-byte Folded Reload
+; RV32IFD-NEXT:    addi sp, sp, 48
+; RV32IFD-NEXT:    ret
+;
+; RV64IFD-LABEL: test_frexp_f128_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:    addi a2, sp, 4
+; RV64IFD-NEXT:    call frexpl at plt
+; RV64IFD-NEXT:    lw a0, 4(sp)
+; RV64IFD-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64IFD-NEXT:    addi sp, sp, 16
+; RV64IFD-NEXT:    ret
+;
+; RV32IZFINXZDINX-LABEL: test_frexp_f128_i32_only_use_exp:
+; RV32IZFINXZDINX:       # %bb.0:
+; RV32IZFINXZDINX-NEXT:    addi sp, sp, -48
+; RV32IZFINXZDINX-NEXT:    sw ra, 44(sp) # 4-byte Folded Spill
+; RV32IZFINXZDINX-NEXT:    lw a3, 0(a0)
+; RV32IZFINXZDINX-NEXT:    lw a1, 4(a0)
+; RV32IZFINXZDINX-NEXT:    lw a2, 8(a0)
+; RV32IZFINXZDINX-NEXT:    lw a0, 12(a0)
+; RV32IZFINXZDINX-NEXT:    sw a0, 20(sp)
+; RV32IZFINXZDINX-NEXT:    sw a2, 16(sp)
+; RV32IZFINXZDINX-NEXT:    sw a1, 12(sp)
+; RV32IZFINXZDINX-NEXT:    addi a0, sp, 24
+; RV32IZFINXZDINX-NEXT:    addi a1, sp, 8
+; RV32IZFINXZDINX-NEXT:    addi a2, sp, 40
+; RV32IZFINXZDINX-NEXT:    sw a3, 8(sp)
+; RV32IZFINXZDINX-NEXT:    call frexpl at plt
+; RV32IZFINXZDINX-NEXT:    lw a0, 40(sp)
+; RV32IZFINXZDINX-NEXT:    lw ra, 44(sp) # 4-byte Folded Reload
+; RV32IZFINXZDINX-NEXT:    addi sp, sp, 48
+; RV32IZFINXZDINX-NEXT:    ret
+;
+; RV64IZFINXZDINX-LABEL: test_frexp_f128_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:    addi a2, sp, 4
+; RV64IZFINXZDINX-NEXT:    call frexpl at plt
+; RV64IZFINXZDINX-NEXT:    lw a0, 4(sp)
+; RV64IZFINXZDINX-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64IZFINXZDINX-NEXT:    addi sp, sp, 16
+; RV64IZFINXZDINX-NEXT:    ret
+  %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a)
+  %result.0 = extractvalue { fp128, i32 } %result, 1
+  ret i32 %result.0
+}
 
 declare { float, i32 } @llvm.frexp.f32.i32(float) #0
 declare { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float>) #0


        


More information about the llvm-commits mailing list