[Mlir-commits] [mlir] [mlir][arith] Do not preserve nneg when folding extui of extui (PR #216315)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Fri Aug 14 06:16:25 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir-arith

Author: William Moses (wsmoses)

<details>
<summary>Changes</summary>

The `extui(extui(x))` fold reassigns the outer extension's source while keeping its `nneg` flag. The flag asserts the source is non-negative as a signed value, about which the outer flag says nothing once the source changes:

```mlir
%w = arith.extui %b : i1 to i8
%r = arith.extui %w nneg : i8 to i32   // satisfied for every bool byte
```

folds to `arith.extui %b nneg : i1 to i32`, which is poison whenever `%b` is true (the signed value of i1 `1` is −1). Downstream, LLVM is then entitled to fold the bool to false everywhere the merged value flows; we hit this as a real end-to-end miscompile where a kernel's boolean-derived launch arguments were all evaluated with the flag's false arm.

Keep `nneg` on the merged extension only if the inner extension carries it — the inner flag is the one that speaks about the surviving source.

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


2 Files Affected:

- (modified) mlir/lib/Dialect/Arith/IR/ArithOps.cpp (+2) 
- (modified) mlir/test/Dialect/Arith/canonicalize.mlir (+18) 


``````````diff
diff --git a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
index 1b7ef01ec64ac..451c24c4df6bd 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
@@ -1822,6 +1822,8 @@ convertFloatValue(APFloat sourceValue,
 
 OpFoldResult arith::ExtUIOp::fold(FoldAdaptor adaptor) {
   if (auto lhs = getIn().getDefiningOp<ExtUIOp>()) {
+    if (!lhs.getNonNeg())
+      setNonNeg(false);
     getInMutable().assign(lhs.getIn());
     return getResult();
   }
diff --git a/mlir/test/Dialect/Arith/canonicalize.mlir b/mlir/test/Dialect/Arith/canonicalize.mlir
index 3761d434b5254..dd3c3abc45bf2 100644
--- a/mlir/test/Dialect/Arith/canonicalize.mlir
+++ b/mlir/test/Dialect/Arith/canonicalize.mlir
@@ -451,6 +451,24 @@ func.func @extUIOfExtUI(%arg0: i1) -> i64 {
   return %ext2 : i64
 }
 
+// CHECK-LABEL: @extUIOfExtUI_outer_nneg
+//       CHECK:   %[[res:.+]] = arith.extui %arg0 : i1 to i64
+//       CHECK:   return %[[res]]
+func.func @extUIOfExtUI_outer_nneg(%arg0: i1) -> i64 {
+  %ext1 = arith.extui %arg0 : i1 to i8
+  %ext2 = arith.extui %ext1 nneg : i8 to i64
+  return %ext2 : i64
+}
+
+// CHECK-LABEL: @extUIOfExtUI_nneg
+//       CHECK:   %[[res:.+]] = arith.extui %arg0 nneg : i8 to i64
+//       CHECK:   return %[[res]]
+func.func @extUIOfExtUI_nneg(%arg0: i8) -> i64 {
+  %ext1 = arith.extui %arg0 nneg : i8 to i32
+  %ext2 = arith.extui %ext1 nneg : i32 to i64
+  return %ext2 : i64
+}
+
 // CHECK-LABEL: @extSIOfExtSI
 //       CHECK:   %[[res:.+]] = arith.extsi %arg0 : i1 to i64
 //       CHECK:   return %[[res]]

``````````

</details>


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


More information about the Mlir-commits mailing list