[Mlir-commits] [mlir] 907dd67 - [MLIR][LLVM] Avoid narrowing wide constant shift amounts (#220777)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Sep 2 18:47:30 PDT 2026


Author: Oscar Priego
Date: 2026-09-03T10:47:25+09:00
New Revision: 907dd67f959483a8b5dd12aa28dfc3bdb3469311

URL: https://github.com/llvm/llvm-project/commit/907dd67f959483a8b5dd12aa28dfc3bdb3469311
DIFF: https://github.com/llvm/llvm-project/commit/907dd67f959483a8b5dd12aa28dfc3bdb3469311.diff

LOG: [MLIR][LLVM] Avoid narrowing wide constant shift amounts (#220777)

LLVM::ShlOp::fold() used APInt::getZExtValue() to compare a constant
shift
amount against the operand bit width.

For wide integer constants whose active value exceeds 64 bits, such as
an i128
shift amount of 2^100, getZExtValue() asserts before the fold can
determine
that the shift is out of range.

Compare the APInt directly with the operand bit width using uge()
instead. This
preserves the existing behavior for out-of-range shifts, which are
currently
left unfolded, while avoiding the unsafe narrowing.

Add regression coverage for:
- a wide out-of-range shift amount
- the exact bit-width boundary
- the largest valid shift amount

Fixes #220610.

Added: 
    

Modified: 
    mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
    mlir/test/Dialect/LLVMIR/constant-folding.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 3758a11dd7bec..4b4d0f098e559 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -4112,8 +4112,7 @@ OpFoldResult LLVM::ShlOp::fold(FoldAdaptor adaptor) {
   if (!rhs)
     return {};
 
-  if (rhs.getValue().getZExtValue() >=
-      getLhs().getType().getIntOrFloatBitWidth())
+  if (rhs.getValue().uge(getLhs().getType().getIntOrFloatBitWidth()))
     return {}; // TODO: Fold into poison.
 
   auto lhs = dyn_cast_or_null<IntegerAttr>(adaptor.getLhs());

diff  --git a/mlir/test/Dialect/LLVMIR/constant-folding.mlir b/mlir/test/Dialect/LLVMIR/constant-folding.mlir
index 777213e067c26..0a6227bd2607b 100644
--- a/mlir/test/Dialect/LLVMIR/constant-folding.mlir
+++ b/mlir/test/Dialect/LLVMIR/constant-folding.mlir
@@ -40,6 +40,40 @@ llvm.func @shl_multiple() -> i32 {
   llvm.return %2 : i32
 }
 
+// CHECK-LABEL: llvm.func @shl_wide_out_of_range_shift
+llvm.func @shl_wide_out_of_range_shift() -> i128 {
+  // CHECK-DAG: %[[LHS:.*]] = llvm.mlir.constant(1 : i128) : i128
+  %lhs = llvm.mlir.constant(1 : i128) : i128
+  // CHECK-DAG: %[[RHS:.*]] = llvm.mlir.constant(1267650600228229401496703205376 : i128) : i128
+  %rhs = llvm.mlir.constant(1267650600228229401496703205376 : i128) : i128
+  // CHECK: %[[RESULT:.*]] = llvm.shl %[[LHS]], %[[RHS]] : i128
+  %result = llvm.shl %lhs, %rhs : i128
+  // CHECK: llvm.return %[[RESULT]] : i128
+  llvm.return %result : i128
+}
+
+// CHECK-LABEL: llvm.func @shl_boundary_out_of_range_shift
+llvm.func @shl_boundary_out_of_range_shift() -> i128 {
+  // CHECK-DAG: %[[LHS:.*]] = llvm.mlir.constant(1 : i128) : i128
+  %lhs = llvm.mlir.constant(1 : i128) : i128
+  // CHECK-DAG: %[[RHS:.*]] = llvm.mlir.constant(128 : i128) : i128
+  %rhs = llvm.mlir.constant(128 : i128) : i128
+  // CHECK: %[[RESULT:.*]] = llvm.shl %[[LHS]], %[[RHS]] : i128
+  %result = llvm.shl %lhs, %rhs : i128
+  // CHECK: llvm.return %[[RESULT]] : i128
+  llvm.return %result : i128
+}
+
+// CHECK-LABEL: llvm.func @shl_largest_valid_shift
+llvm.func @shl_largest_valid_shift() -> i128 {
+  %lhs = llvm.mlir.constant(1 : i128) : i128
+  %rhs = llvm.mlir.constant(127 : i128) : i128
+  %result = llvm.shl %lhs, %rhs : i128
+  // CHECK: %[[RES:.*]] = llvm.mlir.constant(-170141183460469231731687303715884105728 : i128) : i128
+  // CHECK: llvm.return %[[RES]] : i128
+  llvm.return %result : i128
+}
+
 // -----
 
 // CHECK-LABEL: llvm.func @or_basic


        


More information about the Mlir-commits mailing list