[llvm] 67c9a6c - [InstCombine] Drop poison-generating annotations when rewriting rotate operands (#224228)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 17 03:10:51 PDT 2026
Author: Chennes
Date: 2026-09-17T10:10:45Z
New Revision: 67c9a6cbf0b5cd78d2223342ec9f07c903b559e1
URL: https://github.com/llvm/llvm-project/commit/67c9a6cbf0b5cd78d2223342ec9f07c903b559e1
DIFF: https://github.com/llvm/llvm-project/commit/67c9a6cbf0b5cd78d2223342ec9f07c903b559e1.diff
LOG: [InstCombine] Drop poison-generating annotations when rewriting rotate operands (#224228)
`SimplifyDemandedUseBits()` rewrites an operand of a rotate to the
constant formed from its known bits, which preserves only the demanded
bits of the result. A `range` attribute or `!range` metadata on the call
may no longer hold afterwards, turning a defined result into poison:
https://alive2.llvm.org/ce/z/Lk8Eop
#173864 extended annotation dropping in the funnel shift path directly
above to cover metadata; the rotate path never had it.
Drop the annotations in both rotate operand rewrite paths.
Fixes #222092.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
llvm/test/Transforms/InstCombine/fsh.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 34a2da3bf03f2..7d35907e96bea 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -1134,6 +1134,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
if (DemandedMaskLHS.isSubsetOf(LHSKnown.Zero | LHSKnown.One) &&
!match(I->getOperand(0), m_SpecificInt(LHSKnown.One))) {
replaceOperand(*I, 0, Constant::getIntegerValue(VTy, LHSKnown.One));
+ // Range attribute or metadata may no longer hold.
+ I->dropPoisonGeneratingAnnotations();
return I;
}
@@ -1141,6 +1143,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
if (DemandedMaskRHS.isSubsetOf(RHSKnown.Zero | RHSKnown.One) &&
!match(I->getOperand(1), m_SpecificInt(RHSKnown.One))) {
replaceOperand(*I, 1, Constant::getIntegerValue(VTy, RHSKnown.One));
+ // Range attribute or metadata may no longer hold.
+ I->dropPoisonGeneratingAnnotations();
return I;
}
}
diff --git a/llvm/test/Transforms/InstCombine/fsh.ll b/llvm/test/Transforms/InstCombine/fsh.ll
index 453d12be4375f..4ced6099792ac 100644
--- a/llvm/test/Transforms/InstCombine/fsh.ll
+++ b/llvm/test/Transforms/InstCombine/fsh.ll
@@ -1,6 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+declare i8 @llvm.fshl.i8(i8, i8, i8)
declare i16 @llvm.fshl.i16(i16, i16, i16)
declare i16 @llvm.fshr.i16(i16, i16, i16)
declare i32 @llvm.fshl.i32(i32, i32, i32)
@@ -1171,6 +1172,38 @@ define <2 x i8> @fshl_range_vec(<2 x i1> %x) {
ret <2 x i8> %tr
}
+;; Issue #222092 Range attribute no longer holds after a rotate operand is
+;; rewritten.
+
+; The other operand is a load, which the revisit cannot simplify further. For a
+; loaded value of 26 the rotate returns 52, which is in [50, 56), while
+; rewriting the LHS to its known bits (24) returns 48, which is not.
+define i8 @fshl_rotate_range_attr_lhs(ptr %p) {
+; CHECK-LABEL: @fshl_rotate_range_attr_lhs(
+; CHECK-NEXT: [[X:%.*]] = load i8, ptr [[P:%.*]], align 1, !range [[RNG0:![0-9]+]]
+; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.fshl.i8(i8 24, i8 [[X]], i8 1)
+; CHECK-NEXT: [[M:%.*]] = and i8 [[R]], 17
+; CHECK-NEXT: ret i8 [[M]]
+;
+ %x = load i8, ptr %p, align 1, !range !{i8 -104, i8 -100, i8 24, i8 28}
+ %r = call range(i8 50, 56) i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 1)
+ %m = and i8 %r, 17
+ ret i8 %m
+}
+
+; The other operand is a bare argument. For x = 48 the rotate returns 3, which
+; is in [3, 64), while rewriting the RHS to its known bits (32) returns 2.
+define i8 @fshl_rotate_range_attr_rhs(i8 range(i8 32, 64) %x) {
+; CHECK-LABEL: @fshl_rotate_range_attr_rhs(
+; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 32, i8 4)
+; CHECK-NEXT: [[M:%.*]] = and i8 [[R]], 50
+; CHECK-NEXT: ret i8 [[M]]
+;
+ %r = call range(i8 3, 64) i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 4)
+ %m = and i8 %r, 50
+ ret i8 %m
+}
+
;; Issue #138334 negative rotate amounts can be folded into the opposite direction
define i32 @fshl_neg_amount(i32 %x, i32 %y) {
; CHECK-LABEL: @fshl_neg_amount(
More information about the llvm-commits
mailing list