From 2c936fd61afd04fb7ade0159f18f7ef2497eebca Mon Sep 17 00:00:00 2001 From: Shilei Tian Date: Tue, 23 Sep 2025 12:31:03 -0400 Subject: [PATCH 1/2] [AMDGPU] Support `xor cond, -1` when lowering `BRCOND` This can happen when `xor cond, -1` is not combined. --- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 23 ++++++++++++++++--- .../CodeGen/AMDGPU/lower-brcond-with-xor.ll | 23 +++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 llvm/test/CodeGen/AMDGPU/lower-brcond-with-xor.ll diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 0c3bfecce2d9f..01d5e013b7c11 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -7540,17 +7540,34 @@ SDValue SITargetLowering::LowerBRCOND(SDValue BRCOND, SelectionDAG &DAG) const { SDNode *BR = nullptr; SDNode *SetCC = nullptr; - if (Intr->getOpcode() == ISD::SETCC) { + switch (Intr->getOpcode()) { + case ISD::SETCC: { // As long as we negate the condition everything is fine SetCC = Intr; Intr = SetCC->getOperand(0).getNode(); - - } else { + break; + } + case ISD::XOR: { + // Similar to SETCC, if we have (xor c, -1) or (xor -1, c), we will be fine. + SDValue LHS = Intr->getOperand(0); + SDValue RHS = Intr->getOperand(1); + if (auto *C = dyn_cast(LHS); C && C->getZExtValue()) { + Intr = RHS.getNode(); + break; + } + if (auto *C = dyn_cast(RHS); C && C->getZExtValue()) { + Intr = LHS.getNode(); + break; + } + [[fallthrough]]; + } + default: { // Get the target from BR if we don't negate the condition BR = findUser(BRCOND, ISD::BR); assert(BR && "brcond missing unconditional branch user"); Target = BR->getOperand(1); } + } unsigned CFNode = isCFIntrinsic(Intr); if (CFNode == 0) { diff --git a/llvm/test/CodeGen/AMDGPU/lower-brcond-with-xor.ll b/llvm/test/CodeGen/AMDGPU/lower-brcond-with-xor.ll new file mode 100644 index 0000000000000..e2f8df0448f82 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/lower-brcond-with-xor.ll @@ -0,0 +1,23 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a --debug-counter=dagcombine=0 -start-before=si-annotate-control-flow %s -o - | FileCheck %s + +define amdgpu_kernel void @test(i32 %N, ptr addrspace(1) %p) { +; CHECK-LABEL: test: +; CHECK: ; %bb.0: ; %entry +; CHECK-NEXT: v_and_b32_e32 v0, 0x3ff, v0 +; CHECK-NEXT: v_cmp_gt_i32_e32 vcc, 1, v0 +; CHECK-NEXT: s_and_saveexec_b64 s[0:1], vcc +; CHECK-NEXT: s_endpgm +entry: + %id.x = tail call i32 @llvm.amdgcn.workitem.id.x() + %cmp2 = icmp slt i32 %id.x, 1 + br i1 %cmp2, label %if.then, label %exit + +if.then: + %idx.ext = zext i32 %N to i64 + %add.ptr = getelementptr i8, ptr addrspace(1) %p, i64 %idx.ext + ret void + +exit: + ret void +} From 8aa43956ac221f0b3ef455cedf7adf0886891ec3 Mon Sep 17 00:00:00 2001 From: Shilei Tian Date: Tue, 23 Sep 2025 14:48:13 -0400 Subject: [PATCH 2/2] assume canonical form --- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 01d5e013b7c11..5a9036f748655 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -7548,13 +7548,9 @@ SDValue SITargetLowering::LowerBRCOND(SDValue BRCOND, SelectionDAG &DAG) const { break; } case ISD::XOR: { - // Similar to SETCC, if we have (xor c, -1) or (xor -1, c), we will be fine. + // Similar to SETCC, if we have (xor c, -1), we will be fine. SDValue LHS = Intr->getOperand(0); SDValue RHS = Intr->getOperand(1); - if (auto *C = dyn_cast(LHS); C && C->getZExtValue()) { - Intr = RHS.getNode(); - break; - } if (auto *C = dyn_cast(RHS); C && C->getZExtValue()) { Intr = LHS.getNode(); break;