summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Jiang <jtony@ca.ibm.com>2017-12-21 15:42:50 +0000
committerTony Jiang <jtony@ca.ibm.com>2017-12-21 15:42:50 +0000
commiteba757e45c4573c331cd54eb86099ab4163e839f (patch)
tree0aac2a28c6c9e3935f6598c3c70f291eadbb0826
parent4dd03ed7e3aa22b3223687b2f2325e25fc2dbcc4 (diff)
downloadbcm5719-llvm-eba757e45c4573c331cd54eb86099ab4163e839f.tar.gz
bcm5719-llvm-eba757e45c4573c331cd54eb86099ab4163e839f.zip
[PowerPC] Fix parest build failure in SPEC2017.
The build failure was caused by an assertion in pre-legalization DAGCombine: Combining: t6: ppcf128 = uint_to_fp t5 ... into: t20: f32 = PPCISD::FCFIDUS t19 which is clearly wrong since ppcf128 are definitely different type with f32 and we cannot change the node value type when do DAGCombine. The fix is don't handle ppc_fp128 or i1 conversions in PPCTargetLowering::combineFPToIntToFP and leave it to downstream to legalize it and expand it to small legal types. Differential Revision: https://reviews.llvm.org/D41411 llvm-svn: 321276
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp11
-rw-r--r--llvm/test/CodeGen/PowerPC/uint-to-ppcfp128-crash.ll15
2 files changed, 21 insertions, 5 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 18e567fa589..cea59de3e8a 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -11882,6 +11882,12 @@ SDValue PPCTargetLowering::combineFPToIntToFP(SDNode *N,
SDLoc dl(N);
SDValue Op(N, 0);
+ // Don't handle ppc_fp128 here or i1 conversions.
+ if (Op.getValueType() != MVT::f32 && Op.getValueType() != MVT::f64)
+ return SDValue();
+ if (Op.getOperand(0).getValueType() == MVT::i1)
+ return SDValue();
+
SDValue FirstOperand(Op.getOperand(0));
bool SubWordLoad = FirstOperand.getOpcode() == ISD::LOAD &&
(FirstOperand.getValueType() == MVT::i8 ||
@@ -11910,11 +11916,6 @@ SDValue PPCTargetLowering::combineFPToIntToFP(SDNode *N,
return DAG.getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
}
- // Don't handle ppc_fp128 here or i1 conversions.
- if (Op.getValueType() != MVT::f32 && Op.getValueType() != MVT::f64)
- return SDValue();
- if (Op.getOperand(0).getValueType() == MVT::i1)
- return SDValue();
// For i32 intermediate values, unfortunately, the conversion functions
// leave the upper 32 bits of the value are undefined. Within the set of
diff --git a/llvm/test/CodeGen/PowerPC/uint-to-ppcfp128-crash.ll b/llvm/test/CodeGen/PowerPC/uint-to-ppcfp128-crash.ll
new file mode 100644
index 00000000000..ad8dd90ea92
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/uint-to-ppcfp128-crash.ll
@@ -0,0 +1,15 @@
+; RUN: llc -verify-machineinstrs -mcpu=pwr9 \
+; RUN: -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s
+
+; Ensure we don't crash by trying to convert directly from a subword load
+; to a ppc_fp128 as we do for conversions to f32/f64.
+define ppc_fp128 @test(i16* nocapture readonly %Ptr) {
+entry:
+ %0 = load i16, i16* %Ptr, align 2
+ %conv = uitofp i16 %0 to ppc_fp128
+ ret ppc_fp128 %conv
+; CHECK: lhz [[LD:[0-9]+]], 0(3)
+; CHECK: mtvsrwa [[MV:[0-9]+]], [[LD]]
+; CHECK: xscvsxddp [[CONV:[0-9]+]], [[MV]]
+; CHECK: bl __gcc_qadd
+}
OpenPOWER on IntegriCloud