Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ 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())); Index: llvm/test/CodeGen/AArch64/dag-combine-concat-vectors.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AArch64/dag-combine-concat-vectors.ll @@ -0,0 +1,18 @@ +; RUN: llc -O3 -mtriple=aarch64-linux-gnu -mattr=+sve < %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 }