[llvm] [AMDGPU] Use `S_BFE_U64` for uniform i1 ext (PR #69703)

Jay Foad via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 25 07:32:55 PDT 2023


================
@@ -2278,17 +2278,34 @@ def : GCNPat <
   (REG_SEQUENCE SReg_64, $src, sub0, (i32 (IMPLICIT_DEF)), sub1)
 >;
 
-class ZExt_i64_i1_Pat <SDNode ext> : GCNPat <
-  (i64 (ext i1:$src)),
-    (REG_SEQUENCE VReg_64,
-      (V_CNDMASK_B32_e64 /*src0mod*/(i32 0), /*src0*/(i32 0),
-                         /*src1mod*/(i32 0), /*src1*/(i32 1), $src),
-      sub0, (S_MOV_B32 (i32 0)), sub1)
->;
+multiclass ZExt_i64_i1_Pat <SDNode ext> {
+  def: GCNPat <
+    (i64 (ext i1:$src)),
+      (REG_SEQUENCE VReg_64,
+        (V_CNDMASK_B32_e64 /*src0mod*/(i32 0), /*src0*/(i32 0),
+                           /*src1mod*/(i32 0), /*src1*/(i32 1), $src),
+        sub0, (S_MOV_B32 (i32 0)), sub1)
+  >;
+
+  let WaveSizePredicate = isWave32 in
+  def : GCNPat <
+    (i64 (UniformUnaryFrag<ext> SReg_1:$src)),
+    (S_BFE_U64 (REG_SEQUENCE SReg_64,
+                  SReg_32:$src, sub0,
+                  (i32 (IMPLICIT_DEF)), sub1),
+                (i32 0x10000))
+  >;
+
+  let WaveSizePredicate = isWave64 in
+  def : GCNPat <
+    (i64 (UniformUnaryFrag<ext> SReg_1:$src)),
+    (S_BFE_U64 SReg_64:$src, (i32 0x10000))
+  >;
----------------
jayfoad wrote:

I have taken a fresh look at this. I don't think treating $src as an SReg_32/64 can work here, because sdag treats them as i1 values and they are only lowered to 32/64-bit lane masks later in SILowerI1Copies.

This seems to work (and is simpler):
```suggestion
  def : GCNPat <
    (i64 (UniformUnaryFrag<ext> SCC)),
    (S_CSELECT_B64 (i64 1), (i64 0))
  >;
```

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


More information about the llvm-commits mailing list