[llvm] [AMDGPU] Support `xor cond, -1` when lowering `BRCOND` (PR #160341)
Shilei Tian via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 23 11:48:51 PDT 2025
https://github.com/shiltian updated https://github.com/llvm/llvm-project/pull/160341
>From 2c936fd61afd04fb7ade0159f18f7ef2497eebca Mon Sep 17 00:00:00 2001
From: Shilei Tian <i at tianshilei.me>
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<ConstantSDNode>(LHS); C && C->getZExtValue()) {
+ Intr = RHS.getNode();
+ break;
+ }
+ if (auto *C = dyn_cast<ConstantSDNode>(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 <i at tianshilei.me>
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<ConstantSDNode>(LHS); C && C->getZExtValue()) {
- Intr = RHS.getNode();
- break;
- }
if (auto *C = dyn_cast<ConstantSDNode>(RHS); C && C->getZExtValue()) {
Intr = LHS.getNode();
break;
More information about the llvm-commits
mailing list