]> granicus.if.org Git - llvm/commitdiff
Merging r278002:
authorHans Wennborg <hans@hanshq.net>
Wed, 10 Aug 2016 16:27:26 +0000 (16:27 +0000)
committerHans Wennborg <hans@hanshq.net>
Wed, 10 Aug 2016 16:27:26 +0000 (16:27 +0000)
------------------------------------------------------------------------
r278002 | sbaranga | 2016-08-08 06:13:57 -0700 (Mon, 08 Aug 2016) | 18 lines

[AArch64] PR28877: Don't assume we're running after legalization when creating vcvtfp2fxs

Summary:
The DAG combine transformation that was generating the
aarch64_neon_vcvtfp2fxs node was assuming that all
inputs where legal and wasn't accounting that the input
could be a v4f64 if we're trying to do the transformation
before legalization. We now bail out in this case.

All illegal types besides v4f64 were already rejected.

Fixes https://llvm.org/bugs/show_bug.cgi?id=28877.

Reviewers: jmolloy

Subscribers: aemerson, rengolin, llvm-commits

Differential Revision: https://reviews.llvm.org/D23261
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_39@278239 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64ISelLowering.cpp
test/CodeGen/AArch64/aarch64-vcvtfp2fxs-combine.ll [new file with mode: 0644]

index d6f2a190d4c85e8258d80eb17a88a585eeef8843..ac7de1b422e06e24c42fb5592cf94902c4d1af69 100644 (file)
@@ -7685,6 +7685,7 @@ static SDValue performIntToFpCombine(SDNode *N, SelectionDAG &DAG,
 /// Fold a floating-point multiply by power of two into floating-point to
 /// fixed-point conversion.
 static SDValue performFpToIntCombine(SDNode *N, SelectionDAG &DAG,
+                                     TargetLowering::DAGCombinerInfo &DCI,
                                      const AArch64Subtarget *Subtarget) {
   if (!Subtarget->hasNEON())
     return SDValue();
@@ -7728,10 +7729,16 @@ static SDValue performFpToIntCombine(SDNode *N, SelectionDAG &DAG,
     ResTy = FloatBits == 32 ? MVT::v2i32 : MVT::v2i64;
     break;
   case 4:
-    ResTy = MVT::v4i32;
+    ResTy = FloatBits == 32 ? MVT::v4i32 : MVT::v4i64;
     break;
   }
 
+  if (ResTy == MVT::v4i64 && DCI.isBeforeLegalizeOps())
+    return SDValue();
+
+  assert((ResTy != MVT::v4i64 || DCI.isBeforeLegalizeOps()) &&
+         "Illegal vector type after legalization");
+
   SDLoc DL(N);
   bool IsSigned = N->getOpcode() == ISD::FP_TO_SINT;
   unsigned IntrinsicOpcode = IsSigned ? Intrinsic::aarch64_neon_vcvtfp2fxs
@@ -9853,7 +9860,7 @@ SDValue AArch64TargetLowering::PerformDAGCombine(SDNode *N,
     return performIntToFpCombine(N, DAG, Subtarget);
   case ISD::FP_TO_SINT:
   case ISD::FP_TO_UINT:
-    return performFpToIntCombine(N, DAG, Subtarget);
+    return performFpToIntCombine(N, DAG, DCI, Subtarget);
   case ISD::FDIV:
     return performFDivCombine(N, DAG, Subtarget);
   case ISD::OR:
diff --git a/test/CodeGen/AArch64/aarch64-vcvtfp2fxs-combine.ll b/test/CodeGen/AArch64/aarch64-vcvtfp2fxs-combine.ll
new file mode 100644 (file)
index 0000000..a71b5e8
--- /dev/null
@@ -0,0 +1,24 @@
+; RUN: llc < %s -mtriple=aarch64-linux-eabi -o - | FileCheck %s
+
+%struct.a= type { i64, i64, i64, i64 }
+
+; DAG combine will try to perform a transformation that  creates a vcvtfp2fxs
+; with a v4f64 input. Since v4i64 is not legal we should bail out. We can
+; pottentially still create the vcvtfp2fxs node after legalization (but on a
+; v2f64).
+
+; CHECK-LABEL: fun1
+define void @fun1() local_unnamed_addr {
+entry:
+  %mul = fmul <4 x double> zeroinitializer, <double 6.553600e+04, double 6.553600e+04, double 6.553600e+04, double 6.553600e+04>
+  %toi = fptosi <4 x double> %mul to <4 x i64>
+  %ptr = getelementptr inbounds %struct.a, %struct.a* undef, i64 0, i32 2
+  %elem = extractelement <4 x i64> %toi, i32 1
+  store i64 %elem, i64* %ptr, align 8
+  call void @llvm.trap()
+  unreachable
+}
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.trap()
+