[llvm] [AMDGPU] Add v2i32 V_BFI combines for andn2 and orn2 (PR #196325)

via llvm-commits llvm-commits at lists.llvm.org
Thu May 7 07:28:59 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Harrison Hao (harrisonGPU)

<details>
<summary>Changes</summary>

Add vector v2i32 pattern matches that lower to two lane wise V_BFI_B32 operations.

TODO: Support v2i16, v4i16 pattern.

---
Full diff: https://github.com/llvm/llvm-project/pull/196325.diff


3 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/AMDGPUInstructions.td (+1) 
- (modified) llvm/lib/Target/AMDGPU/SIInstructions.td (+32) 
- (modified) llvm/test/CodeGen/AMDGPU/andorn2.ll (+31) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td b/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td
index 529b2990f9b3a..cc7e4816caeec 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td
@@ -262,6 +262,7 @@ def xor_oneuse : HasOneUseBinOp<xor>;
 } // Properties = [SDNPCommutative, SDNPAssociative]
 
 def not_oneuse : HasOneUseUnaryOp<not>;
+def vnot_oneuse : HasOneUseUnaryOp<vnot>;
 
 def add_oneuse : HasOneUseBinOp<add>;
 def sub_oneuse : HasOneUseBinOp<sub>;
diff --git a/llvm/lib/Target/AMDGPU/SIInstructions.td b/llvm/lib/Target/AMDGPU/SIInstructions.td
index d1033c81a9361..408835e9e73b8 100644
--- a/llvm/lib/Target/AMDGPU/SIInstructions.td
+++ b/llvm/lib/Target/AMDGPU/SIInstructions.td
@@ -2735,6 +2735,18 @@ def : AMDGPUPatIgnoreCopies <
               (i32 (EXTRACT_SUBREG VReg_64:$z, sub1))), sub1)
 >;
 
+// v2i32 version
+def : AMDGPUPatIgnoreCopies <
+  (DivergentBinFrag<or> (and v2i32:$y, v2i32:$x), (and v2i32:$z, (vnot v2i32:$x))),
+  (REG_SEQUENCE VReg_64,
+    (V_BFI_B32_e64 (i32 (EXTRACT_SUBREG VReg_64:$x, sub0)),
+              (i32 (EXTRACT_SUBREG VReg_64:$y, sub0)),
+              (i32 (EXTRACT_SUBREG VReg_64:$z, sub0))), sub0,
+    (V_BFI_B32_e64 (i32 (EXTRACT_SUBREG VReg_64:$x, sub1)),
+              (i32 (EXTRACT_SUBREG VReg_64:$y, sub1)),
+              (i32 (EXTRACT_SUBREG VReg_64:$z, sub1))), sub1)
+>;
+
 // (z & ~x)
 def : AMDGPUPatIgnoreCopies <
   (DivergentBinFrag<and> i32:$z, (not_oneuse i32:$x)),
@@ -2751,6 +2763,16 @@ def : AMDGPUPatIgnoreCopies <
                    (i32 (EXTRACT_SUBREG VReg_64:$z, sub1))), sub1)
 >;
 
+// v2i32 version
+def : AMDGPUPatIgnoreCopies <
+  (DivergentBinFrag<and> v2i32:$z, (vnot_oneuse v2i32:$x)),
+  (REG_SEQUENCE VReg_64,
+    (V_BFI_B32_e64 (i32 (EXTRACT_SUBREG VReg_64:$x, sub0)), (i32 0),
+                   (i32 (EXTRACT_SUBREG VReg_64:$z, sub0))), sub0,
+    (V_BFI_B32_e64 (i32 (EXTRACT_SUBREG VReg_64:$x, sub1)), (i32 0),
+                   (i32 (EXTRACT_SUBREG VReg_64:$z, sub1))), sub1)
+>;
+
 // (y | ~x)
 def : AMDGPUPatIgnoreCopies <
   (DivergentBinFrag<or> i32:$y, (not_oneuse i32:$x)),
@@ -2767,6 +2789,16 @@ def : AMDGPUPatIgnoreCopies <
                    (i32 (EXTRACT_SUBREG VReg_64:$y, sub1)), (i32 -1)), sub1)
 >;
 
+// v2i32 version
+def : AMDGPUPatIgnoreCopies <
+  (DivergentBinFrag<or> v2i32:$y, (vnot_oneuse v2i32:$x)),
+  (REG_SEQUENCE VReg_64,
+    (V_BFI_B32_e64 (i32 (EXTRACT_SUBREG VReg_64:$x, sub0)),
+                   (i32 (EXTRACT_SUBREG VReg_64:$y, sub0)), (i32 -1)), sub0,
+    (V_BFI_B32_e64 (i32 (EXTRACT_SUBREG VReg_64:$x, sub1)),
+                   (i32 (EXTRACT_SUBREG VReg_64:$y, sub1)), (i32 -1)), sub1)
+>;
+
 // SHA-256 Ch function
 // z ^ (x & (y ^ z))
 def : AMDGPUPatIgnoreCopies <
diff --git a/llvm/test/CodeGen/AMDGPU/andorn2.ll b/llvm/test/CodeGen/AMDGPU/andorn2.ll
index 1527d50e28b35..ac91102f9daeb 100644
--- a/llvm/test/CodeGen/AMDGPU/andorn2.ll
+++ b/llvm/test/CodeGen/AMDGPU/andorn2.ll
@@ -95,5 +95,36 @@ entry:
   ret void
 }
 
+; GCN-LABEL: {{^}}vector_bfi_v2i32
+; GCN: v_bfi_b32
+; GCN: v_bfi_b32
+define <2 x i32> @vector_bfi_v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> %z) {
+  %ny = and <2 x i32> %y, %x
+  %nx = xor <2 x i32> %x, <i32 -1, i32 -1>
+  %nz = and <2 x i32> %z, %nx
+  %r = or <2 x i32> %ny, %nz
+  ret <2 x i32> %r
+}
+
+; GCN-LABEL: {{^}}vector_andn2_v2i32_one_use
+; GCN: v_bfi_b32
+; GCN: v_bfi_b32
+define <2 x i32> @vector_andn2_v2i32_one_use(<2 x i32> %v, <2 x i32> %s) {
+entry:
+  %not = xor <2 x i32> %v, <i32 -1, i32 -1>
+  %r = and <2 x i32> %s, %not
+  ret <2 x i32> %r
+}
+
+; GCN-LABEL: {{^}}vector_orn2_v2i32_one_use
+; GCN: v_bfi_b32
+; GCN: v_bfi_b32
+define <2 x i32> @vector_orn2_v2i32_one_use(<2 x i32> %v, <2 x i32> %s) {
+entry:
+  %not = xor <2 x i32> %v, <i32 -1, i32 -1>
+  %r = or <2 x i32> %s, %not
+  ret <2 x i32> %r
+}
+
 ; Function Attrs: nounwind readnone
 declare i32 @llvm.amdgcn.workitem.id.x() #0

``````````

</details>


https://github.com/llvm/llvm-project/pull/196325


More information about the llvm-commits mailing list