diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -23167,7 +23167,19 @@ // If the input is a concat_vectors, just make a larger concat by padding // with smaller undefs. - if (In.getOpcode() == ISD::CONCAT_VECTORS && In.hasOneUse()) { + // + // https://github.com/llvm/llvm-project/issues/63322 + // + // We've found an infinite loop caused by legalizing & combining + // CONCAT_VECTORS. The legalizing happens in + // AArch64TargetLowering::LowerCONCAT_VECTORS() and only when LegalDAG is + // true. The corresponding combining happens here. + // + // To fix the issue, we skip the combining if LegalDAG is true. We also + // make sure targets which does not support SVE are not affected by this + // change. + if (In.getOpcode() == ISD::CONCAT_VECTORS && In.hasOneUse() && + (!In.getValueType().isScalableVector() || !LegalDAG)) { unsigned NumOps = N->getNumOperands() * In.getNumOperands(); SmallVector Ops(In->op_begin(), In->op_end()); Ops.resize(NumOps, DAG.getUNDEF(Ops[0].getValueType())); diff --git a/llvm/test/CodeGen/AArch64/aarch64-sve-concat_vectors.ll b/llvm/test/CodeGen/AArch64/aarch64-sve-concat_vectors.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/aarch64-sve-concat_vectors.ll @@ -0,0 +1,18 @@ +; RUN: llc -O3 -mcpu=neoverse-n2 < %s | FileCheck %s +; CHECK: @allocno_reload_assign + +; Function Attrs: nocallback nofree nosync nounwind willreturn writeonly +declare void @llvm.masked.scatter.nxv16i8.nxv16p0(, , i32 immarg, ) #0 + +define fastcc i8 @allocno_reload_assign() { + br label %1 + +1: ; preds = %1, %0 + call void @llvm.masked.scatter.nxv16i8.nxv16p0( zeroinitializer, zeroinitializer, i32 0, xor ( shufflevector ( icmp eq ( insertelement ( poison, ptr null, i64 0), zeroinitializer), poison, zeroinitializer), shufflevector ( insertelement ( poison, i1 true, i32 0), poison, zeroinitializer))) + br label %1 +} + +; uselistorder directives +uselistorder poison, { 1, 2, 0 } + +attributes #0 = { nocallback nofree nosync nounwind willreturn writeonly }