[llvm] 46864f3 - [InstSimplify] Simplify `(shl nsw nuw X, BitWidth - 1)` -> `0`
Noah Goldstein via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 6 18:31:20 PST 2023
Author: Noah Goldstein
Date: 2023-03-06T20:29:53-06:00
New Revision: 46864f3b68f7b0bae192d4c3d4b041713046412e
URL: https://github.com/llvm/llvm-project/commit/46864f3b68f7b0bae192d4c3d4b041713046412e
DIFF: https://github.com/llvm/llvm-project/commit/46864f3b68f7b0bae192d4c3d4b041713046412e.diff
LOG: [InstSimplify] Simplify `(shl nsw nuw X, BitWidth - 1)` -> `0`
https://alive2.llvm.org/ce/z/uFy5zT
Reviewed By: nikic, spatel
Differential Revision: https://reviews.llvm.org/D145327
Added:
Modified:
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstSimplify/shift.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index d6f3585fcc582..abcde1ded6b2c 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1445,10 +1445,11 @@ static Value *simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
simplifyShift(Instruction::Shl, Op0, Op1, IsNSW, Q, MaxRecurse))
return V;
+ Type *Ty = Op0->getType();
// undef << X -> 0
// undef << X -> undef if (if it's NSW/NUW)
if (Q.isUndefValue(Op0))
- return IsNSW || IsNUW ? Op0 : Constant::getNullValue(Op0->getType());
+ return IsNSW || IsNUW ? Op0 : Constant::getNullValue(Ty);
// (X >> A) << A -> X
Value *X;
@@ -1462,6 +1463,13 @@ static Value *simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW,
// NOTE: could use computeKnownBits() / LazyValueInfo,
// but the cost-benefit analysis suggests it isn't worth it.
+ // "nuw" guarantees that only zeros are shifted out, and "nsw" guarantees
+ // that the sign-bit does not change, so the only input that does not
+ // produce poison is 0, and "0 << (bitwidth-1) --> 0".
+ if (IsNSW && IsNUW &&
+ match(Op1, m_SpecificInt(Ty->getScalarSizeInBits() - 1)))
+ return Constant::getNullValue(Ty);
+
return nullptr;
}
diff --git a/llvm/test/Transforms/InstSimplify/shift.ll b/llvm/test/Transforms/InstSimplify/shift.ll
index 4fda696c955a5..83751765df839 100644
--- a/llvm/test/Transforms/InstSimplify/shift.ll
+++ b/llvm/test/Transforms/InstSimplify/shift.ll
@@ -354,8 +354,7 @@ define <vscale x 4 x i16> @lshr_scalable_overshift(<vscale x 4 x i16> %va) {
; shl nsw+nuw is 0
define i8 @shl_nsw_nuw_7_eq_0(i8 %x) {
; CHECK-LABEL: @shl_nsw_nuw_7_eq_0(
-; CHECK-NEXT: [[Y:%.*]] = shl nuw nsw i8 [[X:%.*]], 7
-; CHECK-NEXT: ret i8 [[Y]]
+; CHECK-NEXT: ret i8 0
;
%y = shl nsw nuw i8 %x, 7
ret i8 %y
@@ -364,8 +363,7 @@ define i8 @shl_nsw_nuw_7_eq_0(i8 %x) {
; Make sure we match the element width
define <2 x i8> @shl_vec_nsw_nuw_7_eq_0(<2 x i8> %x) {
; CHECK-LABEL: @shl_vec_nsw_nuw_7_eq_0(
-; CHECK-NEXT: [[Y:%.*]] = shl nuw nsw <2 x i8> [[X:%.*]], <i8 7, i8 7>
-; CHECK-NEXT: ret <2 x i8> [[Y]]
+; CHECK-NEXT: ret <2 x i8> zeroinitializer
;
%y = shl nsw nuw <2 x i8> %x, <i8 7, i8 7>
ret <2 x i8> %y
More information about the llvm-commits
mailing list