From 45ff0a8d76c7efdb08ee7591ffb2e5584693c073 Mon Sep 17 00:00:00 2001 From: Denis Ivanitsa Date: Sun, 5 Nov 2023 23:02:55 +0100 Subject: [PATCH] [InterleavedAccessPass] Avoid optimizing load instructions if it has dead binop users If a load instruction qualifies to be optimized by InterleavedAccess Pass, but also has a dead binop instruction, this will lead to a crash. Binop instruction will not be deleted, because normally it would be deleted through its' users, but it has none. Later on deleting a load instruction will fail because it still has uses. --- llvm/lib/CodeGen/InterleavedAccessPass.cpp | 2 +- .../AArch64/binopshuffles.ll | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/InterleavedAccessPass.cpp b/llvm/lib/CodeGen/InterleavedAccessPass.cpp index 6b3848531569c..65a6859a006a5 100644 --- a/llvm/lib/CodeGen/InterleavedAccessPass.cpp +++ b/llvm/lib/CodeGen/InterleavedAccessPass.cpp @@ -251,7 +251,7 @@ bool InterleavedAccess::lowerInterleavedLoad( continue; } if (auto *BI = dyn_cast(User)) { - if (all_of(BI->users(), [](auto *U) { + if (!BI->user_empty() && all_of(BI->users(), [](auto *U) { auto *SVI = dyn_cast(U); return SVI && isa(SVI->getOperand(1)); })) { diff --git a/llvm/test/Transforms/InterleavedAccess/AArch64/binopshuffles.ll b/llvm/test/Transforms/InterleavedAccess/AArch64/binopshuffles.ll index 67910305f56d6..2e8a7cf42ac50 100644 --- a/llvm/test/Transforms/InterleavedAccess/AArch64/binopshuffles.ll +++ b/llvm/test/Transforms/InterleavedAccess/AArch64/binopshuffles.ll @@ -220,3 +220,24 @@ entry: store <8 x i8> %shuffled, ptr %p2 ret void } + +define void @skip_optimizing_dead_binop(ptr %p0, ptr %p1) { +; CHECK-LABEL: @skip_optimizing_dead_binop( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[V0:%.*]] = load <8 x double>, ptr [[P0:%.*]] +; CHECK-NEXT: [[SHUFFLED_1:%.*]] = shufflevector <8 x double> [[V0]], <8 x double> undef, <2 x i32> +; CHECK-NEXT: [[SHUFFLED_2:%.*]] = shufflevector <8 x double> [[V0]], <8 x double> undef, <2 x i32> +; CHECK-NEXT: [[SHUFFLED_3:%.*]] = shufflevector <8 x double> [[V0]], <8 x double> undef, <2 x i32> +; CHECK-NEXT: [[SHUFFLED_4:%.*]] = shufflevector <8 x double> [[V0]], <8 x double> undef, <2 x i32> +; CHECK-NEXT: [[DEAD_BINOP:%.*]] = fadd <8 x double> [[V0]], [[V0]] +; CHECK-NEXT: ret void +; +entry: + %v0 = load <8 x double>, ptr %p0 + %shuffled_1 = shufflevector <8 x double> %v0, <8 x double> undef, <2 x i32> + %shuffled_2 = shufflevector <8 x double> %v0, <8 x double> undef, <2 x i32> + %shuffled_3 = shufflevector <8 x double> %v0, <8 x double> undef, <2 x i32> + %shuffled_4 = shufflevector <8 x double> %v0, <8 x double> undef, <2 x i32> + %dead_binop = fadd <8 x double> %v0, %v0 + ret void +}