From 52e015081a7768e1ba00a811a8e1a456f8aeecb4 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 31 Mar 2021 09:38:12 +0100 Subject: [PATCH] [AArch64] Avoid SCALAR_TO_VECTOR for single FP constant vector. Currently the code only checks for integer constants (ConstantSDNode) and triggers an infinite cycle for single-element floating point vector constants. We need to check for both FP and integer constants. Reviewed By: t.p.northover Differential Revision: https://reviews.llvm.org/D99384 --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 2 +- llvm/test/CodeGen/AArch64/arm64-build-vector.ll | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index ea71503..5d9d44f 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -9724,7 +9724,7 @@ SDValue AArch64TargetLowering::LowerBUILD_VECTOR(SDValue Op, // 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(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); diff --git a/llvm/test/CodeGen/AArch64/arm64-build-vector.ll b/llvm/test/CodeGen/AArch64/arm64-build-vector.ll index 516da6f..4998574 100644 --- a/llvm/test/CodeGen/AArch64/arm64-build-vector.ll +++ b/llvm/test/CodeGen/AArch64/arm64-build-vector.ll @@ -88,3 +88,20 @@ entry: %add = fadd <1 x double> %arg, 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(i1 %cmp) { +; CHECK-LABEL: convert_single_fp_vector_constant: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: tst w0, #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> , <1 x double> zeroinitializer + ret <1 x double> %sel +} -- 2.7.4