Skip to content

Commit 258d8dd

Browse files
[FPEnv][AArch64] Add lowering and instruction selection for STRICT_FP_ROUND
This gets selected to the appropriate fcvt instruction. Handling from there on isn't fully correct yet, as we need to model fcvt reading and writing to fpsr and fpcr. Differential Revision: https://reviews.llvm.org/D73201
1 parent 727ed11 commit 258d8dd

File tree

3 files changed

+34
-11
lines changed

3 files changed

+34
-11
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
293293
setOperationAction(ISD::UINT_TO_FP, MVT::i128, Custom);
294294
setOperationAction(ISD::FP_ROUND, MVT::f32, Custom);
295295
setOperationAction(ISD::FP_ROUND, MVT::f64, Custom);
296+
setOperationAction(ISD::STRICT_FP_ROUND, MVT::f32, Custom);
297+
setOperationAction(ISD::STRICT_FP_ROUND, MVT::f64, Custom);
296298

297299
// Variable arguments.
298300
setOperationAction(ISD::VASTART, MVT::Other, Custom);
@@ -2521,21 +2523,26 @@ SDValue AArch64TargetLowering::LowerFP_EXTEND(SDValue Op,
25212523

25222524
SDValue AArch64TargetLowering::LowerFP_ROUND(SDValue Op,
25232525
SelectionDAG &DAG) const {
2524-
if (Op.getOperand(0).getValueType() != MVT::f128) {
2526+
bool IsStrict = Op->isStrictFPOpcode();
2527+
SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
2528+
if (SrcVal.getValueType() != MVT::f128) {
25252529
// It's legal except when f128 is involved
25262530
return Op;
25272531
}
25282532

25292533
RTLIB::Libcall LC;
2530-
LC = RTLIB::getFPROUND(Op.getOperand(0).getValueType(), Op.getValueType());
2534+
LC = RTLIB::getFPROUND(SrcVal.getValueType(), Op.getValueType());
25312535

25322536
// FP_ROUND node has a second operand indicating whether it is known to be
25332537
// precise. That doesn't take part in the LibCall so we can't directly use
25342538
// LowerF128Call.
2535-
SDValue SrcVal = Op.getOperand(0);
25362539
MakeLibCallOptions CallOptions;
2537-
return makeLibCall(DAG, LC, Op.getValueType(), SrcVal, CallOptions,
2538-
SDLoc(Op)).first;
2540+
SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
2541+
SDValue Result;
2542+
SDLoc dl(Op);
2543+
std::tie(Result, Chain) = makeLibCall(DAG, LC, Op.getValueType(), SrcVal,
2544+
CallOptions, dl, Chain);
2545+
return IsStrict ? DAG.getMergeValues({Result, Chain}, dl) : Result;
25392546
}
25402547

25412548
SDValue AArch64TargetLowering::LowerVectorFP_TO_INT(SDValue Op,
@@ -3210,6 +3217,7 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
32103217
case ISD::FDIV:
32113218
return LowerF128Call(Op, DAG, RTLIB::DIV_F128);
32123219
case ISD::FP_ROUND:
3220+
case ISD::STRICT_FP_ROUND:
32133221
return LowerFP_ROUND(Op, DAG);
32143222
case ISD::FP_EXTEND:
32153223
return LowerFP_EXTEND(Op, DAG);

llvm/lib/Target/AArch64/AArch64InstrFormats.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4736,11 +4736,11 @@ class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
47364736
multiclass FPConversion<string asm> {
47374737
// Double-precision to Half-precision
47384738
def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
4739-
[(set FPR16:$Rd, (fpround FPR64:$Rn))]>;
4739+
[(set FPR16:$Rd, (any_fpround FPR64:$Rn))]>;
47404740

47414741
// Double-precision to Single-precision
47424742
def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
4743-
[(set FPR32:$Rd, (fpround FPR64:$Rn))]>;
4743+
[(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>;
47444744

47454745
// Half-precision to Double-precision
47464746
def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
@@ -4756,7 +4756,7 @@ multiclass FPConversion<string asm> {
47564756

47574757
// Single-precision to Half-precision
47584758
def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
4759-
[(set FPR16:$Rd, (fpround FPR32:$Rn))]>;
4759+
[(set FPR16:$Rd, (any_fpround FPR32:$Rn))]>;
47604760
}
47614761

47624762
//---

llvm/test/CodeGen/AArch64/fp-intrinsics.ll

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,19 @@ define i64 @fptoui_i64_f32(float %x) #0 {
7777
ret i64 %val
7878
}
7979

80-
; TODO: sitofp_f32_i32 (missing STRICT_FP_ROUND handling)
80+
; CHECK-LABEL: sitofp_f32_i32:
81+
; FIXME-CHECK: scvtf s0, w0
82+
define float @sitofp_f32_i32(i32 %x) #0 {
83+
%val = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
84+
ret float %val
85+
}
8186

82-
; TODO: uitofp_f32_i32 (missing STRICT_FP_ROUND handling)
87+
; CHECK-LABEL: uitofp_f32_i32:
88+
; FIXME-CHECK: ucvtf s0, w0
89+
define float @uitofp_f32_i32(i32 %x) #0 {
90+
%val = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
91+
ret float %val
92+
}
8393

8494
; TODO: sitofp_f32_i64 (missing STRICT_SINT_TO_FP handling)
8595

@@ -880,7 +890,12 @@ define i32 @fcmps_une_f64(double %a, double %b) #0 {
880890

881891
; Single/Double conversion intrinsics
882892

883-
; TODO: fptrunc_f32 (missing STRICT_FP_ROUND handling)
893+
; CHECK-LABEL: fptrunc_f32:
894+
; CHECK: fcvt s0, d0
895+
define float @fptrunc_f32(double %x) #0 {
896+
%val = call float @llvm.experimental.constrained.fptrunc.f32.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
897+
ret float %val
898+
}
884899

885900
; CHECK-LABEL: fpext_f32:
886901
; CHECK: fcvt d0, s0

0 commit comments

Comments
 (0)