From 5bc4ecde2a7c548aab204db3d8f32a8f49508386 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 22 Sep 2025 10:21:39 +0200 Subject: [PATCH] [PowerPC] Avoid working on deleted node in ext bool trunc combine This code was already creating HandleSDNodes to handle the case where a node gets replaced with an equivalent node. However, the code before the handles are created also performs RAUW operations, which can end up CSEing and deleting nodes. Fix this issue by moving the handle creation earlier. --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 10 +++++---- llvm/test/CodeGen/PowerPC/pr160040.ll | 24 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 llvm/test/CodeGen/PowerPC/pr160040.ll diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index fa104e4f69d7f..47e107d11f71b 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -15407,6 +15407,12 @@ SDValue PPCTargetLowering::DAGCombineExtBoolTrunc(SDNode *N, } } + // Convert PromOps to handles before doing any RAUW operations, as these + // may CSE with existing nodes, deleting the originals. + std::list PromOpHandles; + for (auto &PromOp : PromOps) + PromOpHandles.emplace_back(PromOp); + // Replace all inputs, either with the truncation operand, or a // truncation or extension to the final output type. for (unsigned i = 0, ie = Inputs.size(); i != ie; ++i) { @@ -15430,10 +15436,6 @@ SDValue PPCTargetLowering::DAGCombineExtBoolTrunc(SDNode *N, DAG.getAnyExtOrTrunc(InSrc, dl, N->getValueType(0))); } - std::list PromOpHandles; - for (auto &PromOp : PromOps) - PromOpHandles.emplace_back(PromOp); - // Replace all operations (these are all the same, but have a different // (promoted) return type). DAG.getNode will validate that the types of // a binary operator match, so go through the list in reverse so that diff --git a/llvm/test/CodeGen/PowerPC/pr160040.ll b/llvm/test/CodeGen/PowerPC/pr160040.ll new file mode 100644 index 0000000000000..865239b37112c --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/pr160040.ll @@ -0,0 +1,24 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s + +; Make sure this does not crash. +define i32 @test(i32 %arg) { +; CHECK-LABEL: test: +; CHECK: # %bb.0: +; CHECK-NEXT: rlwinm 4, 3, 13, 19, 19 +; CHECK-NEXT: rlwinm 3, 3, 2, 30, 30 +; CHECK-NEXT: xori 4, 4, 4096 +; CHECK-NEXT: xori 3, 3, 2 +; CHECK-NEXT: rlwimi 3, 4, 0, 31, 29 +; CHECK-NEXT: blr + %icmp = icmp sgt i32 %arg, -1 + %select = select i1 %icmp, i16 1, i16 0 + %select1 = select i1 %icmp, i16 16384, i16 0 + %lshr = lshr i16 %select1, 1 + %zext = zext i16 %lshr to i32 + %lshr2 = lshr i32 %zext, 1 + %shl = shl i16 %select, 1 + %zext3 = zext i16 %shl to i32 + %or = or i32 %lshr2, %zext3 + ret i32 %or +}