From b2982a706bc817aef7d12dee1bcba2b53cd8b61f Mon Sep 17 00:00:00 2001 From: George Koehler Date: Wed, 30 Jul 2025 19:43:48 -0400 Subject: [PATCH] [PowerPC] Check ResNo at end of BitPermutationSelector::Select32 If it optimizes away a permutation (rotate all 32 bits left by 0), the result might be from a SDNode with more than one result, such as a load node. The node replacement assumes result number 0. If it isn't 0, kludge by adding an extra node. Fixes https://github.com/llvm/llvm-project/issues/133507 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 5 +++++ llvm/test/CodeGen/PowerPC/lwzu-i48.ll | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 llvm/test/CodeGen/PowerPC/lwzu-i48.ll diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 415164fc9e2cb..710662dc107c5 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -2337,6 +2337,11 @@ class BitPermutationSelector { ANDIVal, ANDISVal), 0); } + // Caller assumes ResNo == 0, but we might have ResNo != 0 after + // optimizing away a permutation. Kludge with an extra node. + if (Res.getResNo() != 0) + return CurDAG->getMachineNode(PPC::OR, dl, MVT::i32, Res, Res); + return Res.getNode(); } diff --git a/llvm/test/CodeGen/PowerPC/lwzu-i48.ll b/llvm/test/CodeGen/PowerPC/lwzu-i48.ll new file mode 100644 index 0000000000000..8205f5976e876 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/lwzu-i48.ll @@ -0,0 +1,19 @@ +; RUN: llc -mtriple=powerpc-unknown-openbsd < %s | FileCheck %s + +; BitPermutationSelector in PPCISelDAGToDAG.cpp was taking the wrong +; result of a load after optimizing away a permutation. +; Here, the big end of i48 %3 was %1 but should be %0. + +define i32 @hop(ptr %out, ptr %in) { +entry: + %0 = getelementptr i8, ptr %in, i32 28 + %1 = load i32, ptr %0, align 4 + %2 = ptrtoint ptr %0 to i48 + %3 = shl i48 %2, 16 + store i48 %3, ptr %out, align 4 + ret i32 %1 +} +; The stw should store POINTER, not VALUE. +; CHECK: lwzu [[VALUE:[0-9]+]], 28([[POINTER:[0-9]+]]) +; CHECK: mr [[MOVED:[0-9]+]], [[POINTER]] +; CHECK: stw [[MOVED]], 0({{[0-9]+}})