summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Brawn <john.brawn@arm.com>2020-02-17 16:55:32 +0000
committerHans Wennborg <hans@chromium.org>2020-02-18 16:46:45 +0100
commitf636e9feb9f0969e3b563d3140db5a0faa1e30d8 (patch)
treedf1a1225567d937f71c53b8fec1329b7f6c95133
parentb5d9a7e72fafaead89f0cc8994925c90ed3169be (diff)
downloadbcm5719-llvm-f636e9feb9f0969e3b563d3140db5a0faa1e30d8.tar.gz
bcm5719-llvm-f636e9feb9f0969e3b563d3140db5a0faa1e30d8.zip
[FPEnv][ARM] Don't call mutateStrictFPToFP when lowering
mutateStrictFPToFP can delete the node and replace it with another with the same value which can later cause problems, and returning the result of mutateStrictFPToFP doesn't work because SelectionDAGLegalize expects that the returned value has the same number of results as the original. Instead handle things by doing the mutation manually. Differential Revision: https://reviews.llvm.org/D74726 (cherry picked from commit 594a89f7270da74c89f2321432bc6a7135773fa5)
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp12
-rw-r--r--llvm/test/CodeGen/ARM/fp-intrinsics.ll45
2 files changed, 55 insertions, 2 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 559a4e8435c..2f836a60a9e 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -5421,7 +5421,12 @@ SDValue ARMTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const {
// FIXME: Remove this when we have strict fp instruction selection patterns
if (IsStrict) {
- DAG.mutateStrictFPToFP(Op.getNode());
+ SDLoc Loc(Op);
+ SDValue Result =
+ DAG.getNode(Op.getOpcode() == ISD::STRICT_FP_TO_SINT ? ISD::FP_TO_SINT
+ : ISD::FP_TO_UINT,
+ Loc, Op.getValueType(), SrcVal);
+ return DAG.getMergeValues({Result, Op.getOperand(0)}, Loc);
}
return Op;
@@ -16384,7 +16389,10 @@ SDValue ARMTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
if (SrcSz == 32 && DstSz == 64 && Subtarget->hasFP64()) {
// FIXME: Remove this when we have strict fp instruction selection patterns
if (IsStrict) {
- DAG.mutateStrictFPToFP(Op.getNode());
+ SDLoc Loc(Op);
+ SDValue Result = DAG.getNode(ISD::FP_EXTEND,
+ Loc, Op.getValueType(), SrcVal);
+ return DAG.getMergeValues({Result, Op.getOperand(0)}, Loc);
}
return Op;
}
diff --git a/llvm/test/CodeGen/ARM/fp-intrinsics.ll b/llvm/test/CodeGen/ARM/fp-intrinsics.ll
index c5746ef7b30..5b81982f652 100644
--- a/llvm/test/CodeGen/ARM/fp-intrinsics.ll
+++ b/llvm/test/CodeGen/ARM/fp-intrinsics.ll
@@ -72,6 +72,21 @@ define i32 @fptosi_f32(float %x) #0 {
ret i32 %val
}
+; CHECK-LABEL: fptosi_f32_twice:
+; CHECK-NOSP: bl __aeabi_f2iz
+; CHECK-NOSP: bl __aeabi_f2iz
+; CHECK-SP: vcvt.s32.f32
+; FIXME-CHECK-SP: vcvt.s32.f32
+define void @fptosi_f32_twice(float %arg, i32* %ptr) #0 {
+entry:
+ %conv = call i32 @llvm.experimental.constrained.fptosi.f32(float %arg, metadata !"fpexcept.strict") #0
+ store i32 %conv, i32* %ptr, align 4
+ %conv1 = call i32 @llvm.experimental.constrained.fptosi.f32(float %arg, metadata !"fpexcept.strict") #0
+ %idx = getelementptr inbounds i32, i32* %ptr, i32 1
+ store i32 %conv1, i32* %idx, align 4
+ ret void
+}
+
; CHECK-LABEL: fptoui_f32:
; CHECK-NOSP: bl __aeabi_f2uiz
; FIXME-CHECK-SP: vcvt.u32.f32
@@ -80,6 +95,21 @@ define i32 @fptoui_f32(float %x) #0 {
ret i32 %val
}
+; CHECK-LABEL: fptoui_f32_twice:
+; CHECK-NOSP: bl __aeabi_f2uiz
+; CHECK-NOSP: bl __aeabi_f2uiz
+; FIXME-CHECK-SP: vcvt.u32.f32
+; FIXME-CHECK-SP: vcvt.u32.f32
+define void @fptoui_f32_twice(float %arg, i32* %ptr) #0 {
+entry:
+ %conv = call i32 @llvm.experimental.constrained.fptoui.f32(float %arg, metadata !"fpexcept.strict") #0
+ store i32 %conv, i32* %ptr, align 4
+ %conv1 = call i32 @llvm.experimental.constrained.fptoui.f32(float %arg, metadata !"fpexcept.strict") #0
+ %idx = getelementptr inbounds i32, i32* %ptr, i32 1
+ store i32 %conv1, i32* %idx, align 4
+ ret void
+}
+
; CHECK-LABEL: sqrt_f32:
; CHECK-NOSP: bl sqrtf
; CHECK-SP: vsqrt.f32
@@ -947,6 +977,21 @@ define double @fpext_f32(float %x) #0 {
ret double %val
}
+; CHECK-LABEL: fpext_f32_twice:
+; CHECK-NODP: bl __aeabi_f2d
+; CHECK-NODP: bl __aeabi_f2d
+; CHECK-DP: vcvt.f64.f32
+; FIXME-CHECK-DP: vcvt.f64.f32
+define void @fpext_f32_twice(float %arg, double* %ptr) #0 {
+entry:
+ %conv1 = call double @llvm.experimental.constrained.fpext.f64.f32(float %arg, metadata !"fpexcept.strict") #0
+ store double %conv1, double* %ptr, align 8
+ %conv2 = call double @llvm.experimental.constrained.fpext.f64.f32(float %arg, metadata !"fpexcept.strict") #0
+ %idx = getelementptr inbounds double, double* %ptr, i32 1
+ store double %conv2, double* %idx, align 8
+ ret void
+}
+
; CHECK-LABEL: sitofp_f32_i32:
; CHECK-NOSP: bl __aeabi_i2f
; FIXME-CHECK-SP: vcvt.f32.s32
OpenPOWER on IntegriCloud