[PATCH] D99384: [AArch64] Avoid SCALAR_TO_VECTOR for single FP constant vector.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 25 14:56:06 PDT 2021


fhahn created this revision.
fhahn added reviewers: t.p.northover, paquette, dmgreen, SjoerdMeijer.
Herald added subscribers: danielkiss, hiraditya, kristof.beyls.
fhahn requested review of this revision.
Herald added a project: LLVM.

Currently the code only checks for integer constants (ConstantSDNode)
and triggers an infinite cycle for single-element floating point
vector constants.

I've added a lambda used in a few places to make sure we always check
for both FP and integer constants.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D99384

Files:
  llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
  llvm/test/CodeGen/AArch64/arm64-build-vector.ll


Index: llvm/test/CodeGen/AArch64/arm64-build-vector.ll
===================================================================
--- llvm/test/CodeGen/AArch64/arm64-build-vector.ll
+++ llvm/test/CodeGen/AArch64/arm64-build-vector.ll
@@ -88,3 +88,20 @@
   %add = fadd <1 x double> %arg, <double 1.0>
   ret <1 x double> %add
 }
+
+; Make sure BUILD_VECTOR does not get stuck in a loop trying to convert a
+; single element FP vector constant from a scalar to vector.
+define <1 x double> @convert_single_fp_vector_constant(<1 x double>* %ptr, i1 %cmp) {
+; CHECK-LABEL: convert_single_fp_vector_constant:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    tst w1, #0x1
+; CHECK-NEXT:    mov x8, #4607182418800017408
+; CHECK-NEXT:    csetm x9, ne
+; CHECK-NEXT:    fmov d0, x8
+; CHECK-NEXT:    fmov d1, x9
+; CHECK-NEXT:    and.8b v0, v0, v1
+; CHECK-NEXT:    ret
+entry:
+  %sel = select i1 %cmp, <1 x double> <double 1.000000e+00>, <1 x double> zeroinitializer
+  ret <1 x double> %sel
+}
Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -9670,6 +9670,10 @@
   unsigned NumUndefLanes = 0;
   SDValue Value;
   SDValue ConstantValue;
+  auto IsIntOrFPConstant = [](SDValue V) {
+    return isa<ConstantSDNode>(V) || isa<ConstantFPSDNode>(V);
+  };
+
   for (unsigned i = 0; i < NumElts; ++i) {
     SDValue V = Op.getOperand(i);
     if (V.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
@@ -9680,10 +9684,10 @@
     }
     if (i > 0)
       isOnlyLowElement = false;
-    if (!isa<ConstantFPSDNode>(V) && !isa<ConstantSDNode>(V))
+    if (!IsIntOrFPConstant(V))
       isConstant = false;
 
-    if (isa<ConstantSDNode>(V) || isa<ConstantFPSDNode>(V)) {
+    if (IsIntOrFPConstant(V)) {
       ++NumConstantLanes;
       if (!ConstantValue.getNode())
         ConstantValue = V;
@@ -9708,7 +9712,7 @@
   // Convert BUILD_VECTOR where all elements but the lowest are undef into
   // SCALAR_TO_VECTOR, except for when we have a single-element constant vector
   // as SimplifyDemandedBits will just turn that back into BUILD_VECTOR.
-  if (isOnlyLowElement && !(NumElts == 1 && isa<ConstantSDNode>(Value))) {
+  if (isOnlyLowElement && !(NumElts == 1 && IsIntOrFPConstant(Value))) {
     LLVM_DEBUG(dbgs() << "LowerBUILD_VECTOR: only low element used, creating 1 "
                          "SCALAR_TO_VECTOR node\n");
     return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D99384.333433.patch
Type: text/x-patch
Size: 2553 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210325/f3f1235f/attachment.bin>


More information about the llvm-commits mailing list