[llvm] [InstCombine] Improve shamt range calculation (PR #72535)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 16 10:37:49 PST 2023


https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/72535

>From 561a3c51afb2816ca1ab20fef16fafc69f590681 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 16 Nov 2023 17:18:07 +0800
Subject: [PATCH 1/2] [InstCombine] Improve shamt range calculation

---
 llvm/include/llvm/Analysis/ValueTracking.h    |  5 ++
 llvm/lib/Analysis/ValueTracking.cpp           |  8 ++--
 .../InstCombine/InstCombineShifts.cpp         | 16 +++----
 .../test/Transforms/InstCombine/and-narrow.ll |  2 +-
 .../InstCombine/binop-of-displaced-shifts.ll  |  4 +-
 .../canonicalize-ashr-shl-to-masking.ll       | 10 ++--
 ...low-bit-mask-v2-and-icmp-eq-to-icmp-ule.ll | 16 +++----
 ...low-bit-mask-v2-and-icmp-ne-to-icmp-ugt.ll | 16 +++----
 ...low-bit-mask-v3-and-icmp-eq-to-icmp-ule.ll |  2 +-
 ...low-bit-mask-v3-and-icmp-ne-to-icmp-ugt.ll |  2 +-
 ...low-bit-mask-v4-and-icmp-eq-to-icmp-ule.ll | 20 ++++----
 ...low-bit-mask-v4-and-icmp-ne-to-icmp-ugt.ll | 20 ++++----
 .../canonicalize-lshr-shl-to-masking.ll       | 10 ++--
 ...e-length-signext-after-high-bit-extract.ll | 48 +++++++++----------
 .../Transforms/InstCombine/icmp-and-shift.ll  |  4 +-
 llvm/test/Transforms/InstCombine/icmp-shr.ll  | 12 ++---
 ...al-to-icmp-eq-of-lshr-val-by-bits-and-0.ll |  2 +-
 ...al-to-icmp-eq-of-lshr-val-by-bits-and-0.ll | 18 +++----
 ...al-to-icmp-ne-of-lshr-val-by-bits-and-0.ll |  2 +-
 ...al-to-icmp-ne-of-lshr-val-by-bits-and-0.ll | 18 +++----
 ...of-two-or-zero-when-comparing-with-zero.ll |  2 +-
 .../Transforms/InstCombine/onehot_merge.ll    | 12 ++---
 ...nput-masking-after-truncation-variant-b.ll | 14 +++---
 ...nput-masking-after-truncation-variant-d.ll | 10 ++--
 ...dant-left-shift-input-masking-variant-b.ll |  8 ++--
 ...dant-left-shift-input-masking-variant-d.ll |  8 ++--
 ...nput-masking-after-truncation-variant-b.ll | 10 ++--
 ...nput-masking-after-truncation-variant-d.ll |  6 +--
 ...dant-left-shift-input-masking-variant-b.ll | 26 +++++-----
 ...dant-left-shift-input-masking-variant-d.ll | 26 +++++-----
 .../redundant-right-shift-input-masking.ll    | 16 +++----
 .../Transforms/InstCombine/shift-shift.ll     |  4 +-
 llvm/test/Transforms/InstCombine/shift.ll     |  2 +-
 llvm/test/Transforms/InstCombine/shl-sub.ll   | 12 ++---
 .../signbit-lshr-and-icmpeq-zero.ll           | 24 +++++-----
 .../sub-of-negatible-inseltpoison.ll          |  2 +-
 .../InstCombine/sub-of-negatible.ll           |  2 +-
 llvm/test/Transforms/InstCombine/sub.ll       |  8 ++--
 38 files changed, 215 insertions(+), 212 deletions(-)

diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 01eb8532d1f56d2..ba7bfcab03482f6 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -888,6 +888,11 @@ ConstantRange computeConstantRange(const Value *V, bool ForSigned,
                                    const DominatorTree *DT = nullptr,
                                    unsigned Depth = 0);
 
+/// Combine constant ranges from computeConstantRange() and computeKnownBits().
+ConstantRange
+computeConstantRangeIncludingKnownBits(const WithCache<const Value *> &V,
+                                       bool ForSigned, const SimplifyQuery &SQ);
+
 /// Return true if this function can prove that the instruction I will
 /// always transfer execution to one of its successors (including the next
 /// instruction that follows within a basic block). E.g. this is not
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 5f5d7e07cac1e46..b166806f0ec0e2a 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6292,10 +6292,10 @@ static OverflowResult mapOverflowResult(ConstantRange::OverflowResult OR) {
 }
 
 /// Combine constant ranges from computeConstantRange() and computeKnownBits().
-static ConstantRange
-computeConstantRangeIncludingKnownBits(const WithCache<const Value *> &V,
-                                       bool ForSigned,
-                                       const SimplifyQuery &SQ) {
+ConstantRange
+llvm::computeConstantRangeIncludingKnownBits(const WithCache<const Value *> &V,
+                                             bool ForSigned,
+                                             const SimplifyQuery &SQ) {
   ConstantRange CR1 =
       ConstantRange::fromKnownBits(V.getKnownBits(SQ), ForSigned);
   ConstantRange CR2 = computeConstantRange(V, ForSigned, SQ.IIQ.UseInstrInfo);
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 9d4a2cc08cca30c..cf87ae3ace5d1a2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -12,6 +12,7 @@
 
 #include "InstCombineInternal.h"
 #include "llvm/Analysis/InstructionSimplify.h"
+#include "llvm/IR/ConstantRange.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/PatternMatch.h"
 #include "llvm/Transforms/InstCombine/InstCombiner.h"
@@ -962,16 +963,13 @@ static bool setShiftFlags(BinaryOperator &I, const SimplifyQuery &Q) {
   }
 
   // Compute what we know about shift count.
-  KnownBits KnownCnt =
-      computeKnownBits(I.getOperand(1), Q.DL, /*Depth*/ 0, Q.AC, Q.CxtI, Q.DT);
-  // If we know nothing about shift count or its a poison shift, we won't be
-  // able to prove anything so return before computing shift amount.
-  if (KnownCnt.isUnknown())
-    return false;
+  ConstantRange KnownCnt = computeConstantRangeIncludingKnownBits(
+      I.getOperand(1), /* ForSigned */ false, Q);
   unsigned BitWidth = KnownCnt.getBitWidth();
-  APInt MaxCnt = KnownCnt.getMaxValue();
-  if (MaxCnt.uge(BitWidth))
-    return false;
+  // Since shift produces a poison value if RHS is equal to or larger than the
+  // bit width, we can safely assume that RHS is less than the bit width.
+  APInt MaxCnt(BitWidth, BitWidth - 1);
+  MaxCnt = APIntOps::umin(MaxCnt, KnownCnt.getUnsignedMax());
 
   KnownBits KnownAmt =
       computeKnownBits(I.getOperand(0), Q.DL, /*Depth*/ 0, Q.AC, Q.CxtI, Q.DT);
diff --git a/llvm/test/Transforms/InstCombine/and-narrow.ll b/llvm/test/Transforms/InstCombine/and-narrow.ll
index c8c720f5fbc5534..0cc74008144b738 100644
--- a/llvm/test/Transforms/InstCombine/and-narrow.ll
+++ b/llvm/test/Transforms/InstCombine/and-narrow.ll
@@ -190,7 +190,7 @@ define <2 x i16> @zext_lshr_vec_undef(<2 x i8> %x) {
 define <2 x i16> @zext_shl_vec_overshift(<2 x i8> %x) {
 ; CHECK-LABEL: @zext_shl_vec_overshift(
 ; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16>
-; CHECK-NEXT:    [[B:%.*]] = shl <2 x i16> [[Z]], <i16 8, i16 2>
+; CHECK-NEXT:    [[B:%.*]] = shl nuw <2 x i16> [[Z]], <i16 8, i16 2>
 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i16> [[B]], [[Z]]
 ; CHECK-NEXT:    ret <2 x i16> [[R]]
 ;
diff --git a/llvm/test/Transforms/InstCombine/binop-of-displaced-shifts.ll b/llvm/test/Transforms/InstCombine/binop-of-displaced-shifts.ll
index 8bfaa23c88bb4ea..78f4550464681e5 100644
--- a/llvm/test/Transforms/InstCombine/binop-of-displaced-shifts.ll
+++ b/llvm/test/Transforms/InstCombine/binop-of-displaced-shifts.ll
@@ -150,9 +150,9 @@ define i8 @lshr_add_fail(i8 %x) {
 define i8 @ashr_add_fail(i8 %x) {
 ; CHECK-LABEL: define i8 @ashr_add_fail
 ; CHECK-SAME: (i8 [[X:%.*]]) {
-; CHECK-NEXT:    [[SHIFT:%.*]] = ashr i8 -128, [[X]]
+; CHECK-NEXT:    [[SHIFT:%.*]] = ashr exact i8 -128, [[X]]
 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X]], 1
-; CHECK-NEXT:    [[SHIFT2:%.*]] = ashr i8 -128, [[ADD]]
+; CHECK-NEXT:    [[SHIFT2:%.*]] = ashr exact i8 -128, [[ADD]]
 ; CHECK-NEXT:    [[BINOP:%.*]] = add i8 [[SHIFT]], [[SHIFT2]]
 ; CHECK-NEXT:    ret i8 [[BINOP]]
 ;
diff --git a/llvm/test/Transforms/InstCombine/canonicalize-ashr-shl-to-masking.ll b/llvm/test/Transforms/InstCombine/canonicalize-ashr-shl-to-masking.ll
index 00e2bdf7b8ef83e..cde8efbafc5e5a8 100644
--- a/llvm/test/Transforms/InstCombine/canonicalize-ashr-shl-to-masking.ll
+++ b/llvm/test/Transforms/InstCombine/canonicalize-ashr-shl-to-masking.ll
@@ -15,7 +15,7 @@
 
 define i8 @positive_samevar(i8 %x, i8 %y) {
 ; CHECK-LABEL: @positive_samevar(
-; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[RET:%.*]] = and i8 [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[RET]]
 ;
@@ -62,7 +62,7 @@ define i8 @positive_biggershl(i8 %x) {
 
 define i8 @positive_samevar_shlnuw(i8 %x, i8 %y) {
 ; CHECK-LABEL: @positive_samevar_shlnuw(
-; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[RET:%.*]] = and i8 [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[RET]]
 ;
@@ -109,7 +109,7 @@ define i8 @positive_biggershl_shlnuw(i8 %x) {
 
 define i8 @positive_samevar_shlnsw(i8 %x, i8 %y) {
 ; CHECK-LABEL: @positive_samevar_shlnsw(
-; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[RET:%.*]] = and i8 [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[RET]]
 ;
@@ -156,7 +156,7 @@ define i8 @positive_biggershl_shlnsw(i8 %x) {
 
 define i8 @positive_samevar_shlnuwnsw(i8 %x, i8 %y) {
 ; CHECK-LABEL: @positive_samevar_shlnuwnsw(
-; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[RET:%.*]] = and i8 [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[RET]]
 ;
@@ -371,7 +371,7 @@ define i8 @positive_biggershl_shlnuwnsw_ashrexact(i8 %x) {
 
 define <2 x i8> @positive_samevar_vec(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @positive_samevar_vec(
-; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i8> <i8 -1, i8 -1>, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl nsw <2 x i8> <i8 -1, i8 -1>, [[Y:%.*]]
 ; CHECK-NEXT:    [[RET:%.*]] = and <2 x i8> [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret <2 x i8> [[RET]]
 ;
diff --git a/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v2-and-icmp-eq-to-icmp-ule.ll b/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v2-and-icmp-eq-to-icmp-ule.ll
index 624b9baa372810a..dfd67eae8aafd42 100644
--- a/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v2-and-icmp-eq-to-icmp-ule.ll
+++ b/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v2-and-icmp-eq-to-icmp-ule.ll
@@ -142,7 +142,7 @@ declare void @use8(i8)
 
 define i1 @oneuse0(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[X_HIGHBITS:%.*]] = lshr i8 [[X:%.*]], [[Y]]
 ; CHECK-NEXT:    [[RET:%.*]] = icmp eq i8 [[X_HIGHBITS]], 0
@@ -158,7 +158,7 @@ define i1 @oneuse0(i8 %x, i8 %y) {
 
 define i1 @oneuse1(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
 ; CHECK-NEXT:    [[RET:%.*]] = icmp uge i8 [[T1]], [[X:%.*]]
@@ -174,7 +174,7 @@ define i1 @oneuse1(i8 %x, i8 %y) {
 
 define i1 @oneuse2(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T2]])
@@ -191,7 +191,7 @@ define i1 @oneuse2(i8 %x, i8 %y) {
 
 define i1 @oneuse3(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse3(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
@@ -209,7 +209,7 @@ define i1 @oneuse3(i8 %x, i8 %y) {
 
 define i1 @oneuse4(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse4(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
@@ -228,7 +228,7 @@ define i1 @oneuse4(i8 %x, i8 %y) {
 
 define i1 @oneuse5(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse5(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
@@ -253,7 +253,7 @@ define i1 @oneuse5(i8 %x, i8 %y) {
 
 define i1 @n0(i8 %x, i8 %y, i8 %notx) {
 ; CHECK-LABEL: @n0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    [[RET:%.*]] = icmp eq i8 [[T2]], [[NOTX:%.*]]
@@ -283,7 +283,7 @@ define i1 @n1(i8 %x, i8 %y) {
 
 define i1 @n2(i8 %x, i8 %y) {
 ; CHECK-LABEL: @n2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], 1
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
diff --git a/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v2-and-icmp-ne-to-icmp-ugt.ll b/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v2-and-icmp-ne-to-icmp-ugt.ll
index 4e1b90a476a2601..608e133ec7f73cd 100644
--- a/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v2-and-icmp-ne-to-icmp-ugt.ll
+++ b/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v2-and-icmp-ne-to-icmp-ugt.ll
@@ -142,7 +142,7 @@ declare void @use8(i8)
 
 define i1 @oneuse0(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[X_HIGHBITS:%.*]] = lshr i8 [[X:%.*]], [[Y]]
 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne i8 [[X_HIGHBITS]], 0
@@ -158,7 +158,7 @@ define i1 @oneuse0(i8 %x, i8 %y) {
 
 define i1 @oneuse1(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
 ; CHECK-NEXT:    [[RET:%.*]] = icmp ult i8 [[T1]], [[X:%.*]]
@@ -174,7 +174,7 @@ define i1 @oneuse1(i8 %x, i8 %y) {
 
 define i1 @oneuse2(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T2]])
@@ -191,7 +191,7 @@ define i1 @oneuse2(i8 %x, i8 %y) {
 
 define i1 @oneuse3(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse3(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
@@ -209,7 +209,7 @@ define i1 @oneuse3(i8 %x, i8 %y) {
 
 define i1 @oneuse4(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse4(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
@@ -228,7 +228,7 @@ define i1 @oneuse4(i8 %x, i8 %y) {
 
 define i1 @oneuse5(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse5(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
@@ -253,7 +253,7 @@ define i1 @oneuse5(i8 %x, i8 %y) {
 
 define i1 @n0(i8 %x, i8 %y, i8 %notx) {
 ; CHECK-LABEL: @n0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne i8 [[T2]], [[NOTX:%.*]]
@@ -283,7 +283,7 @@ define i1 @n1(i8 %x, i8 %y) {
 
 define i1 @n2(i8 %x, i8 %y) {
 ; CHECK-LABEL: @n2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], 1
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
diff --git a/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v3-and-icmp-eq-to-icmp-ule.ll b/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v3-and-icmp-eq-to-icmp-ule.ll
index 75de1dc6d07a222..a65be1e9ceeca3c 100644
--- a/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v3-and-icmp-eq-to-icmp-ule.ll
+++ b/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v3-and-icmp-eq-to-icmp-ule.ll
@@ -249,7 +249,7 @@ define i1 @n0(i8 %x, i8 %y, i8 %notx) {
 
 define i1 @n1(i8 %x, i8 %y) {
 ; CHECK-LABEL: @n1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0]], -1
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
diff --git a/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v3-and-icmp-ne-to-icmp-ugt.ll b/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v3-and-icmp-ne-to-icmp-ugt.ll
index a92f4a9d9543112..f156d9bf007cbb0 100644
--- a/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v3-and-icmp-ne-to-icmp-ugt.ll
+++ b/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v3-and-icmp-ne-to-icmp-ugt.ll
@@ -249,7 +249,7 @@ define i1 @n0(i8 %x, i8 %y, i8 %notx) {
 
 define i1 @n1(i8 %x, i8 %y) {
 ; CHECK-LABEL: @n1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0]], -1
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
diff --git a/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v4-and-icmp-eq-to-icmp-ule.ll b/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v4-and-icmp-eq-to-icmp-ule.ll
index 4ff27b787ed4e15..81f9fe4a3d181a2 100644
--- a/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v4-and-icmp-eq-to-icmp-ule.ll
+++ b/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v4-and-icmp-eq-to-icmp-ule.ll
@@ -20,7 +20,7 @@ declare void @use3i8(<3 x i8>)
 
 define i1 @p0(i8 %x, i8 %y) {
 ; CHECK-LABEL: @p0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    [[RET:%.*]] = icmp uge i8 [[T1]], [[X:%.*]]
@@ -40,7 +40,7 @@ define i1 @p0(i8 %x, i8 %y) {
 
 define <2 x i1> @p1_vec(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @p1_vec(
-; CHECK-NEXT:    [[T0:%.*]] = shl <2 x i8> <i8 -1, i8 -1>, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw <2 x i8> <i8 -1, i8 -1>, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use2i8(<2 x i8> [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact <2 x i8> [[T0]], [[Y]]
 ; CHECK-NEXT:    [[RET:%.*]] = icmp uge <2 x i8> [[T1]], [[X:%.*]]
@@ -78,7 +78,7 @@ declare i8 @gen8()
 
 define i1 @c0(i8 %y) {
 ; CHECK-LABEL: @c0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    [[X:%.*]] = call i8 @gen8()
@@ -96,7 +96,7 @@ define i1 @c0(i8 %y) {
 
 define i1 @c1(i8 %y) {
 ; CHECK-LABEL: @c1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    [[X:%.*]] = call i8 @gen8()
@@ -114,7 +114,7 @@ define i1 @c1(i8 %y) {
 
 define i1 @c2(i8 %y) {
 ; CHECK-LABEL: @c2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    [[X:%.*]] = call i8 @gen8()
@@ -136,7 +136,7 @@ define i1 @c2(i8 %y) {
 
 define i1 @oneuse0(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
@@ -154,7 +154,7 @@ define i1 @oneuse0(i8 %x, i8 %y) {
 
 define i1 @oneuse1(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
@@ -173,7 +173,7 @@ define i1 @oneuse1(i8 %x, i8 %y) {
 
 define i1 @oneuse2(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
@@ -198,7 +198,7 @@ define i1 @oneuse2(i8 %x, i8 %y) {
 
 define i1 @n0(i8 %x, i8 %y, i8 %notx) {
 ; CHECK-LABEL: @n0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
@@ -230,7 +230,7 @@ define i1 @n1(i8 %x, i8 %y) {
 
 define i1 @n2(i8 %x, i8 %y1, i8 %y2) {
 ; CHECK-LABEL: @n2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y1:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y1:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr i8 [[T0]], [[Y2:%.*]]
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
diff --git a/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v4-and-icmp-ne-to-icmp-ugt.ll b/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v4-and-icmp-ne-to-icmp-ugt.ll
index 3c69d6b4c14a762..321a1159d0af7a8 100644
--- a/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v4-and-icmp-ne-to-icmp-ugt.ll
+++ b/llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v4-and-icmp-ne-to-icmp-ugt.ll
@@ -20,7 +20,7 @@ declare void @use3i8(<3 x i8>)
 
 define i1 @p0(i8 %x, i8 %y) {
 ; CHECK-LABEL: @p0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    [[RET:%.*]] = icmp ult i8 [[T1]], [[X:%.*]]
@@ -40,7 +40,7 @@ define i1 @p0(i8 %x, i8 %y) {
 
 define <2 x i1> @p1_vec(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @p1_vec(
-; CHECK-NEXT:    [[T0:%.*]] = shl <2 x i8> <i8 -1, i8 -1>, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw <2 x i8> <i8 -1, i8 -1>, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use2i8(<2 x i8> [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact <2 x i8> [[T0]], [[Y]]
 ; CHECK-NEXT:    [[RET:%.*]] = icmp ult <2 x i8> [[T1]], [[X:%.*]]
@@ -78,7 +78,7 @@ declare i8 @gen8()
 
 define i1 @c0(i8 %y) {
 ; CHECK-LABEL: @c0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    [[X:%.*]] = call i8 @gen8()
@@ -96,7 +96,7 @@ define i1 @c0(i8 %y) {
 
 define i1 @c1(i8 %y) {
 ; CHECK-LABEL: @c1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    [[X:%.*]] = call i8 @gen8()
@@ -114,7 +114,7 @@ define i1 @c1(i8 %y) {
 
 define i1 @c2(i8 %y) {
 ; CHECK-LABEL: @c2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    [[X:%.*]] = call i8 @gen8()
@@ -136,7 +136,7 @@ define i1 @c2(i8 %y) {
 
 define i1 @oneuse0(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
@@ -154,7 +154,7 @@ define i1 @oneuse0(i8 %x, i8 %y) {
 
 define i1 @oneuse1(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
@@ -173,7 +173,7 @@ define i1 @oneuse1(i8 %x, i8 %y) {
 
 define i1 @oneuse2(i8 %x, i8 %y) {
 ; CHECK-LABEL: @oneuse2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
@@ -198,7 +198,7 @@ define i1 @oneuse2(i8 %x, i8 %y) {
 
 define i1 @n0(i8 %x, i8 %y, i8 %notx) {
 ; CHECK-LABEL: @n0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i8 [[T0]], [[Y]]
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
@@ -230,7 +230,7 @@ define i1 @n1(i8 %x, i8 %y) {
 
 define i1 @n2(i8 %x, i8 %y1, i8 %y2) {
 ; CHECK-LABEL: @n2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[Y1:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[Y1:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = lshr i8 [[T0]], [[Y2:%.*]]
 ; CHECK-NEXT:    [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
diff --git a/llvm/test/Transforms/InstCombine/canonicalize-lshr-shl-to-masking.ll b/llvm/test/Transforms/InstCombine/canonicalize-lshr-shl-to-masking.ll
index 0b8165e577133e9..501967f0c901e65 100644
--- a/llvm/test/Transforms/InstCombine/canonicalize-lshr-shl-to-masking.ll
+++ b/llvm/test/Transforms/InstCombine/canonicalize-lshr-shl-to-masking.ll
@@ -15,7 +15,7 @@
 
 define i8 @positive_samevar(i8 %x, i8 %y) {
 ; CHECK-LABEL: @positive_samevar(
-; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[RET:%.*]] = and i8 [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[RET]]
 ;
@@ -62,7 +62,7 @@ define i8 @positive_biggershl(i8 %x) {
 
 define i8 @positive_samevar_shlnuw(i8 %x, i8 %y) {
 ; CHECK-LABEL: @positive_samevar_shlnuw(
-; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[RET:%.*]] = and i8 [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[RET]]
 ;
@@ -109,7 +109,7 @@ define i8 @positive_biggershl_shlnuw(i8 %x) {
 
 define i8 @positive_samevar_shlnsw(i8 %x, i8 %y) {
 ; CHECK-LABEL: @positive_samevar_shlnsw(
-; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[RET:%.*]] = and i8 [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[RET]]
 ;
@@ -156,7 +156,7 @@ define i8 @positive_biggershl_shlnsw(i8 %x) {
 
 define i8 @positive_samevar_shlnuwnsw(i8 %x, i8 %y) {
 ; CHECK-LABEL: @positive_samevar_shlnuwnsw(
-; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 -1, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl nsw i8 -1, [[Y:%.*]]
 ; CHECK-NEXT:    [[RET:%.*]] = and i8 [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[RET]]
 ;
@@ -371,7 +371,7 @@ define i8 @positive_biggershl_shlnuwnsw_lshrexact(i8 %x) {
 
 define <2 x i8> @positive_samevar_vec(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @positive_samevar_vec(
-; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i8> <i8 -1, i8 -1>, [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl nsw <2 x i8> <i8 -1, i8 -1>, [[Y:%.*]]
 ; CHECK-NEXT:    [[RET:%.*]] = and <2 x i8> [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret <2 x i8> [[RET]]
 ;
diff --git a/llvm/test/Transforms/InstCombine/conditional-variable-length-signext-after-high-bit-extract.ll b/llvm/test/Transforms/InstCombine/conditional-variable-length-signext-after-high-bit-extract.ll
index cdcd8a8abd1f0e6..5569af452de4fcc 100644
--- a/llvm/test/Transforms/InstCombine/conditional-variable-length-signext-after-high-bit-extract.ll
+++ b/llvm/test/Transforms/InstCombine/conditional-variable-length-signext-after-high-bit-extract.ll
@@ -19,7 +19,7 @@ define i32 @t0_notrunc_add(i32 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
@@ -50,7 +50,7 @@ define i32 @t0_notrunc_or(i32 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
@@ -114,7 +114,7 @@ define i32 @t2_trunc_add(i64 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
 ; CHECK-NEXT:    call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
@@ -151,7 +151,7 @@ define i32 @t2_trunc_or(i64 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
 ; CHECK-NEXT:    call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
@@ -225,7 +225,7 @@ define i32 @t4_commutativity0(i32 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
@@ -255,7 +255,7 @@ define i32 @t5_commutativity1(i32 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp sgt i32 [[DATA]], -1
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 0, i32 [[ALL_BITS_EXCEPT_LOW_NBITS]]
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
@@ -285,7 +285,7 @@ define i32 @t6_commutativity2(i32 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
@@ -320,7 +320,7 @@ define i32 @t7_trunc_extrause0(i64 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
 ; CHECK-NEXT:    call void @use64(i64 [[HIGH_BITS_EXTRACTED_WIDE]])
@@ -355,7 +355,7 @@ define i32 @t8_trunc_extrause1(i64 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP_WIDE:%.*]] = zext i32 [[LOW_BITS_TO_SKIP]] to i64
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
@@ -392,7 +392,7 @@ define i32 @n9_trunc_extrause2(i64 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
@@ -429,7 +429,7 @@ define i32 @t10_preserve_exact(i32 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr exact i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
@@ -463,7 +463,7 @@ define i32 @t11_different_zext_of_shamt(i32 %data, i8 %nbits) {
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_32]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
 ; CHECK-NEXT:    [[NBITS_32BIT:%.*]] = zext i8 [[NBITS]] to i32
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS_32BIT]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS_32BIT]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
 ; CHECK-NEXT:    call void @use16(i16 [[NBITS_16BIT]])
 ; CHECK-NEXT:    call void @use16(i16 [[LOW_BITS_TO_SKIP]])
@@ -505,7 +505,7 @@ define i32 @t12_add_sext_of_magic(i32 %data, i8 %nbits) {
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
 ; CHECK-NEXT:    [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i16 -1, [[NBITS_16BIT]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i16 -1, [[NBITS_16BIT]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 0
 ; CHECK-NEXT:    [[MAGIC_WIDE:%.*]] = sext i16 [[MAGIC]] to i32
 ; CHECK-NEXT:    call void @use32(i32 [[NBITS_32BIT]])
@@ -591,7 +591,7 @@ define i32 @t14_add_sext_of_shl(i32 %data, i8 %nbits) {
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
 ; CHECK-NEXT:    [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i16 -1, [[NBITS_16BIT]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i16 -1, [[NBITS_16BIT]]
 ; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE:%.*]] = sext i16 [[ALL_BITS_EXCEPT_LOW_NBITS]] to i32
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS_WIDE]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[NBITS_32BIT]])
@@ -677,7 +677,7 @@ define i32 @n16(i32 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP:%.*]] = sub i32 31, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
@@ -739,7 +739,7 @@ define i32 @n18(i32 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 0, i32 [[ALL_BITS_EXCEPT_LOW_NBITS]]
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
@@ -770,7 +770,7 @@ define i32 @n19(i32 %data1, i32 %data2, i32 %nbits) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA1:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA2:%.*]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
@@ -801,7 +801,7 @@ define i32 @n20(i32 %data, i32 %nbits1, i32 %nbits2) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS1:%.*]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS2:%.*]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS2:%.*]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
@@ -832,7 +832,7 @@ define i32 @n21(i32 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp sgt i32 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
@@ -865,7 +865,7 @@ define i32 @n22(i64 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED_WIDE:%.*]] = lshr i64 [[DATA:%.*]], [[LOW_BITS_TO_SKIP_WIDE]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = trunc i64 [[HIGH_BITS_EXTRACTED_WIDE]] to i32
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i64 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use64(i64 [[LOW_BITS_TO_SKIP_WIDE]])
@@ -902,7 +902,7 @@ define i32 @n23(i32 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = ashr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
@@ -964,7 +964,7 @@ define i32 @n25_sub(i32 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT:    [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[HIGHER_BIT_AFTER_SIGNBIT:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[HIGHER_BIT_AFTER_SIGNBIT]], i32 0
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
@@ -995,7 +995,7 @@ define i32 @n26(i32 %data, i32 %nbits) {
 ; CHECK-NEXT:    [[LOW_BITS_TO_SKIP:%.*]] = sub i32 32, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i32 -1, [[NBITS]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i32 -1, [[NBITS]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i32 [[ALL_BITS_EXCEPT_LOW_NBITS]], i32 -1
 ; CHECK-NEXT:    call void @use32(i32 [[LOW_BITS_TO_SKIP]])
 ; CHECK-NEXT:    call void @use32(i32 [[HIGH_BITS_EXTRACTED]])
@@ -1028,7 +1028,7 @@ define i32 @n27_add_zext_of_magic(i32 %data, i8 %nbits) {
 ; CHECK-NEXT:    [[HIGH_BITS_EXTRACTED:%.*]] = lshr i32 [[DATA:%.*]], [[LOW_BITS_TO_SKIP]]
 ; CHECK-NEXT:    [[SHOULD_SIGNEXT:%.*]] = icmp slt i32 [[DATA]], 0
 ; CHECK-NEXT:    [[NBITS_16BIT:%.*]] = zext i8 [[NBITS]] to i16
-; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl i16 -1, [[NBITS_16BIT]]
+; CHECK-NEXT:    [[ALL_BITS_EXCEPT_LOW_NBITS:%.*]] = shl nsw i16 -1, [[NBITS_16BIT]]
 ; CHECK-NEXT:    [[MAGIC:%.*]] = select i1 [[SHOULD_SIGNEXT]], i16 [[ALL_BITS_EXCEPT_LOW_NBITS]], i16 0
 ; CHECK-NEXT:    [[MAGIC_WIDE:%.*]] = zext i16 [[MAGIC]] to i32
 ; CHECK-NEXT:    call void @use32(i32 [[NBITS_32BIT]])
diff --git a/llvm/test/Transforms/InstCombine/icmp-and-shift.ll b/llvm/test/Transforms/InstCombine/icmp-and-shift.ll
index f9a4ec67b77e24e..b0d4dabb7384093 100644
--- a/llvm/test/Transforms/InstCombine/icmp-and-shift.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-and-shift.ll
@@ -462,7 +462,7 @@ define <2 x i1> @ne_and_shl_one_commute(<2 x i8> %x, <2 x i8> %y) {
 define i1 @ne_and_lshr_minval(i8 %px, i8 %y) {
 ; CHECK-LABEL: @ne_and_lshr_minval(
 ; CHECK-NEXT:    [[X:%.*]] = mul i8 [[PX:%.*]], [[PX]]
-; CHECK-NEXT:    [[POW2:%.*]] = lshr i8 -128, [[Y:%.*]]
+; CHECK-NEXT:    [[POW2:%.*]] = lshr exact i8 -128, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[POW2]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[AND]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
@@ -477,7 +477,7 @@ define i1 @ne_and_lshr_minval(i8 %px, i8 %y) {
 define i1 @eq_and_lshr_minval_commute(i8 %px, i8 %y) {
 ; CHECK-LABEL: @eq_and_lshr_minval_commute(
 ; CHECK-NEXT:    [[X:%.*]] = mul i8 [[PX:%.*]], [[PX]]
-; CHECK-NEXT:    [[POW2:%.*]] = lshr i8 -128, [[Y:%.*]]
+; CHECK-NEXT:    [[POW2:%.*]] = lshr exact i8 -128, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use(i8 [[POW2]])
 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[POW2]]
 ; CHECK-NEXT:    call void @use(i8 [[AND]])
diff --git a/llvm/test/Transforms/InstCombine/icmp-shr.ll b/llvm/test/Transforms/InstCombine/icmp-shr.ll
index 44beb5c1c578b19..71b4f5a970c2f62 100644
--- a/llvm/test/Transforms/InstCombine/icmp-shr.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-shr.ll
@@ -1046,7 +1046,7 @@ define i1 @lshr_pow2_ugt(i8 %x) {
 
 define i1 @lshr_pow2_ugt_use(i8 %x) {
 ; CHECK-LABEL: @lshr_pow2_ugt_use(
-; CHECK-NEXT:    [[S:%.*]] = lshr i8 -128, [[X:%.*]]
+; CHECK-NEXT:    [[S:%.*]] = lshr exact i8 -128, [[X:%.*]]
 ; CHECK-NEXT:    call void @use(i8 [[S]])
 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[X]], 5
 ; CHECK-NEXT:    ret i1 [[R]]
@@ -1094,7 +1094,7 @@ define i1 @lshr_pow2_ugt1(i8 %x) {
 
 define i1 @ashr_pow2_ugt(i8 %x) {
 ; CHECK-LABEL: @ashr_pow2_ugt(
-; CHECK-NEXT:    [[S:%.*]] = ashr i8 -128, [[X:%.*]]
+; CHECK-NEXT:    [[S:%.*]] = ashr exact i8 -128, [[X:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[S]], -96
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
@@ -1107,7 +1107,7 @@ define i1 @ashr_pow2_ugt(i8 %x) {
 
 define i1 @lshr_pow2_sgt(i8 %x) {
 ; CHECK-LABEL: @lshr_pow2_sgt(
-; CHECK-NEXT:    [[S:%.*]] = lshr i8 -128, [[X:%.*]]
+; CHECK-NEXT:    [[S:%.*]] = lshr exact i8 -128, [[X:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[S]], 3
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
@@ -1128,7 +1128,7 @@ define i1 @lshr_pow2_ult(i8 %x) {
 
 define i1 @lshr_pow2_ult_use(i8 %x) {
 ; CHECK-LABEL: @lshr_pow2_ult_use(
-; CHECK-NEXT:    [[S:%.*]] = lshr i8 -128, [[X:%.*]]
+; CHECK-NEXT:    [[S:%.*]] = lshr exact i8 -128, [[X:%.*]]
 ; CHECK-NEXT:    call void @use(i8 [[S]])
 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[X]], 4
 ; CHECK-NEXT:    ret i1 [[R]]
@@ -1186,7 +1186,7 @@ define i1 @lshr_pow2_ult_smin(i8 %x) {
 
 define i1 @ashr_pow2_ult(i8 %x) {
 ; CHECK-LABEL: @ashr_pow2_ult(
-; CHECK-NEXT:    [[S:%.*]] = ashr i8 -128, [[X:%.*]]
+; CHECK-NEXT:    [[S:%.*]] = ashr exact i8 -128, [[X:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[S]], -96
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
@@ -1199,7 +1199,7 @@ define i1 @ashr_pow2_ult(i8 %x) {
 
 define i1 @lshr_pow2_slt(i8 %x) {
 ; CHECK-LABEL: @lshr_pow2_slt(
-; CHECK-NEXT:    [[S:%.*]] = lshr i8 -128, [[X:%.*]]
+; CHECK-NEXT:    [[S:%.*]] = lshr exact i8 -128, [[X:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[S]], 3
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
diff --git a/llvm/test/Transforms/InstCombine/icmp-uge-of-add-of-shl-one-by-bits-to-allones-and-val-to-icmp-eq-of-lshr-val-by-bits-and-0.ll b/llvm/test/Transforms/InstCombine/icmp-uge-of-add-of-shl-one-by-bits-to-allones-and-val-to-icmp-eq-of-lshr-val-by-bits-and-0.ll
index b33ba41dcf31d51..5adf476f7a79fde 100644
--- a/llvm/test/Transforms/InstCombine/icmp-uge-of-add-of-shl-one-by-bits-to-allones-and-val-to-icmp-eq-of-lshr-val-by-bits-and-0.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-uge-of-add-of-shl-one-by-bits-to-allones-and-val-to-icmp-eq-of-lshr-val-by-bits-and-0.ll
@@ -184,7 +184,7 @@ define i1 @oneuse(i8 %val, i8 %bits) {
 
 define i1 @n0(i8 %val, i8 %bits) {
 ; CHECK-LABEL: @n0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0]], -1
 ; CHECK-NEXT:    [[R:%.*]] = icmp uge i8 [[T1]], [[VAL:%.*]]
diff --git a/llvm/test/Transforms/InstCombine/icmp-uge-of-not-of-shl-allones-by-bits-and-val-to-icmp-eq-of-lshr-val-by-bits-and-0.ll b/llvm/test/Transforms/InstCombine/icmp-uge-of-not-of-shl-allones-by-bits-and-val-to-icmp-eq-of-lshr-val-by-bits-and-0.ll
index 001a5475d6afc5b..574f3e23a4ecf5b 100644
--- a/llvm/test/Transforms/InstCombine/icmp-uge-of-not-of-shl-allones-by-bits-and-val-to-icmp-eq-of-lshr-val-by-bits-and-0.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-uge-of-not-of-shl-allones-by-bits-and-val-to-icmp-eq-of-lshr-val-by-bits-and-0.ll
@@ -99,8 +99,8 @@ define i1 @c0(i8 %bits) {
 ; What if we have the same pattern on both sides?
 define i1 @both(i8 %bits0, i8 %bits1) {
 ; CHECK-LABEL: @both(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS0:%.*]]
-; CHECK-NEXT:    [[T2:%.*]] = shl i8 -1, [[BITS1:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS0:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = shl nsw i8 -1, [[BITS1:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp uge i8 [[T2]], [[T0]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
@@ -120,7 +120,7 @@ declare void @use8(i8)
 
 define i1 @oneuse0(i8 %val, i8 %bits) {
 ; CHECK-LABEL: @oneuse0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr i8 [[VAL:%.*]], [[BITS]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[VAL_HIGHBITS]], 0
@@ -135,7 +135,7 @@ define i1 @oneuse0(i8 %val, i8 %bits) {
 
 define i1 @oneuse1(i8 %val, i8 %bits) {
 ; CHECK-LABEL: @oneuse1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
 ; CHECK-NEXT:    [[R:%.*]] = icmp uge i8 [[T1]], [[VAL:%.*]]
@@ -150,7 +150,7 @@ define i1 @oneuse1(i8 %val, i8 %bits) {
 
 define i1 @oneuse2(i8 %val, i8 %bits) {
 ; CHECK-LABEL: @oneuse2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
@@ -184,7 +184,7 @@ define i1 @n0(i8 %val, i8 %bits) {
 
 define i1 @n1(i8 %val, i8 %bits) {
 ; CHECK-LABEL: @n1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], 1
 ; CHECK-NEXT:    [[R:%.*]] = icmp uge i8 [[T1]], [[VAL:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
@@ -210,7 +210,7 @@ define <2 x i1> @n2_vec_nonsplat(<2 x i8> %val, <2 x i8> %bits) {
 
 define <2 x i1> @n3_vec_nonsplat(<2 x i8> %val, <2 x i8> %bits) {
 ; CHECK-LABEL: @n3_vec_nonsplat(
-; CHECK-NEXT:    [[T0:%.*]] = shl <2 x i8> <i8 -1, i8 -1>, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw <2 x i8> <i8 -1, i8 -1>, [[BITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor <2 x i8> [[T0]], <i8 -1, i8 1>
 ; CHECK-NEXT:    [[R:%.*]] = icmp uge <2 x i8> [[T1]], [[VAL:%.*]]
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
@@ -223,7 +223,7 @@ define <2 x i1> @n3_vec_nonsplat(<2 x i8> %val, <2 x i8> %bits) {
 
 define i1 @n3(i8 %val, i8 %bits) {
 ; CHECK-LABEL: @n3(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[T1]], [[VAL:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
@@ -236,7 +236,7 @@ define i1 @n3(i8 %val, i8 %bits) {
 
 define i1 @n4(i8 %bits) {
 ; CHECK-LABEL: @n4(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    [[VAL:%.*]] = call i8 @gen8()
 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[VAL]], [[T1]]
diff --git a/llvm/test/Transforms/InstCombine/icmp-ult-of-add-of-shl-one-by-bits-to-allones-and-val-to-icmp-ne-of-lshr-val-by-bits-and-0.ll b/llvm/test/Transforms/InstCombine/icmp-ult-of-add-of-shl-one-by-bits-to-allones-and-val-to-icmp-ne-of-lshr-val-by-bits-and-0.ll
index 1c46e77486d8964..dd353d44218bf1a 100644
--- a/llvm/test/Transforms/InstCombine/icmp-ult-of-add-of-shl-one-by-bits-to-allones-and-val-to-icmp-ne-of-lshr-val-by-bits-and-0.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-ult-of-add-of-shl-one-by-bits-to-allones-and-val-to-icmp-ne-of-lshr-val-by-bits-and-0.ll
@@ -184,7 +184,7 @@ define i1 @oneuse(i8 %val, i8 %bits) {
 
 define i1 @n0(i8 %val, i8 %bits) {
 ; CHECK-LABEL: @n0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0]], -1
 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[T1]], [[VAL:%.*]]
diff --git a/llvm/test/Transforms/InstCombine/icmp-ult-of-not-of-shl-allones-by-bits-and-val-to-icmp-ne-of-lshr-val-by-bits-and-0.ll b/llvm/test/Transforms/InstCombine/icmp-ult-of-not-of-shl-allones-by-bits-and-val-to-icmp-ne-of-lshr-val-by-bits-and-0.ll
index d8d97681658e466..5f0af994f0eb82b 100644
--- a/llvm/test/Transforms/InstCombine/icmp-ult-of-not-of-shl-allones-by-bits-and-val-to-icmp-ne-of-lshr-val-by-bits-and-0.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-ult-of-not-of-shl-allones-by-bits-and-val-to-icmp-ne-of-lshr-val-by-bits-and-0.ll
@@ -99,8 +99,8 @@ define i1 @c0(i8 %bits) {
 ; What if we have the same pattern on both sides?
 define i1 @both(i8 %bits0, i8 %bits1) {
 ; CHECK-LABEL: @both(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS0:%.*]]
-; CHECK-NEXT:    [[T2:%.*]] = shl i8 -1, [[BITS1:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS0:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = shl nsw i8 -1, [[BITS1:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[T2]], [[T0]]
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
@@ -120,7 +120,7 @@ declare void @use8(i8)
 
 define i1 @oneuse0(i8 %val, i8 %bits) {
 ; CHECK-LABEL: @oneuse0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr i8 [[VAL:%.*]], [[BITS]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[VAL_HIGHBITS]], 0
@@ -135,7 +135,7 @@ define i1 @oneuse0(i8 %val, i8 %bits) {
 
 define i1 @oneuse1(i8 %val, i8 %bits) {
 ; CHECK-LABEL: @oneuse1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[T1]], [[VAL:%.*]]
@@ -150,7 +150,7 @@ define i1 @oneuse1(i8 %val, i8 %bits) {
 
 define i1 @oneuse2(i8 %val, i8 %bits) {
 ; CHECK-LABEL: @oneuse2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
@@ -184,7 +184,7 @@ define i1 @n0(i8 %val, i8 %bits) {
 
 define i1 @n1(i8 %val, i8 %bits) {
 ; CHECK-LABEL: @n1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], 1
 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[T1]], [[VAL:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
@@ -210,7 +210,7 @@ define <2 x i1> @n2_vec_nonsplat(<2 x i8> %val, <2 x i8> %bits) {
 
 define <2 x i1> @n3_vec_nonsplat(<2 x i8> %val, <2 x i8> %bits) {
 ; CHECK-LABEL: @n3_vec_nonsplat(
-; CHECK-NEXT:    [[T0:%.*]] = shl <2 x i8> <i8 -1, i8 -1>, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw <2 x i8> <i8 -1, i8 -1>, [[BITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor <2 x i8> [[T0]], <i8 -1, i8 1>
 ; CHECK-NEXT:    [[R:%.*]] = icmp ult <2 x i8> [[T1]], [[VAL:%.*]]
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
@@ -223,7 +223,7 @@ define <2 x i1> @n3_vec_nonsplat(<2 x i8> %val, <2 x i8> %bits) {
 
 define i1 @n3(i8 %val, i8 %bits) {
 ; CHECK-LABEL: @n3(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[T1]], [[VAL:%.*]]
 ; CHECK-NEXT:    ret i1 [[R]]
@@ -236,7 +236,7 @@ define i1 @n3(i8 %val, i8 %bits) {
 
 define i1 @n4(i8 %bits) {
 ; CHECK-LABEL: @n4(
-; CHECK-NEXT:    [[T0:%.*]] = shl i8 -1, [[BITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i8 [[T0]], -1
 ; CHECK-NEXT:    [[VAL:%.*]] = call i8 @gen8()
 ; CHECK-NEXT:    [[R:%.*]] = icmp uge i8 [[VAL]], [[T1]]
diff --git a/llvm/test/Transforms/InstCombine/omit-urem-of-power-of-two-or-zero-when-comparing-with-zero.ll b/llvm/test/Transforms/InstCombine/omit-urem-of-power-of-two-or-zero-when-comparing-with-zero.ll
index cc791b7358c8fec..c16633efe4ce3cd 100644
--- a/llvm/test/Transforms/InstCombine/omit-urem-of-power-of-two-or-zero-when-comparing-with-zero.ll
+++ b/llvm/test/Transforms/InstCombine/omit-urem-of-power-of-two-or-zero-when-comparing-with-zero.ll
@@ -39,7 +39,7 @@ define i1 @p1_scalar_urem_by_nonconst(i32 %x, i32 %y) {
 define i1 @p2_scalar_shifted_urem_by_const(i32 %x, i32 %y) {
 ; CHECK-LABEL: @p2_scalar_shifted_urem_by_const(
 ; CHECK-NEXT:    [[T0:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[T0]], [[Y:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nuw i32 [[T0]], [[Y:%.*]]
 ; CHECK-NEXT:    [[T2:%.*]] = urem i32 [[T1]], 3
 ; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[T2]], 0
 ; CHECK-NEXT:    ret i1 [[T3]]
diff --git a/llvm/test/Transforms/InstCombine/onehot_merge.ll b/llvm/test/Transforms/InstCombine/onehot_merge.ll
index 3622db419ff4771..228ad233c976342 100644
--- a/llvm/test/Transforms/InstCombine/onehot_merge.ll
+++ b/llvm/test/Transforms/InstCombine/onehot_merge.ll
@@ -334,7 +334,7 @@ define <2 x i1> @foo1_or_commuted_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32>
 define i1 @foo1_and_signbit_lshr(i32 %k, i32 %c1, i32 %c2) {
 ; CHECK-LABEL: @foo1_and_signbit_lshr(
 ; CHECK-NEXT:    [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
-; CHECK-NEXT:    [[T4:%.*]] = lshr i32 -2147483648, [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = lshr exact i32 -2147483648, [[C2:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T]], [[T4]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
 ; CHECK-NEXT:    [[OR:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
@@ -353,7 +353,7 @@ define i1 @foo1_and_signbit_lshr(i32 %k, i32 %c1, i32 %c2) {
 define i1 @foo1_and_signbit_lshr_logical(i32 %k, i32 %c1, i32 %c2) {
 ; CHECK-LABEL: @foo1_and_signbit_lshr_logical(
 ; CHECK-NEXT:    [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
-; CHECK-NEXT:    [[T4:%.*]] = lshr i32 -2147483648, [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = lshr exact i32 -2147483648, [[C2:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = freeze i32 [[T4]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[T]], [[TMP1]]
 ; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], [[K:%.*]]
@@ -373,7 +373,7 @@ define i1 @foo1_and_signbit_lshr_logical(i32 %k, i32 %c1, i32 %c2) {
 define <2 x i1> @foo1_and_signbit_lshr_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
 ; CHECK-LABEL: @foo1_and_signbit_lshr_vector(
 ; CHECK-NEXT:    [[T:%.*]] = shl nuw <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
-; CHECK-NEXT:    [[T4:%.*]] = lshr <2 x i32> <i32 -2147483648, i32 -2147483648>, [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = lshr exact <2 x i32> <i32 -2147483648, i32 -2147483648>, [[C2:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[T]], [[T4]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[K:%.*]]
 ; CHECK-NEXT:    [[OR:%.*]] = icmp ne <2 x i32> [[TMP2]], [[TMP1]]
@@ -392,7 +392,7 @@ define <2 x i1> @foo1_and_signbit_lshr_vector(<2 x i32> %k, <2 x i32> %c1, <2 x
 define i1 @foo1_or_signbit_lshr(i32 %k, i32 %c1, i32 %c2) {
 ; CHECK-LABEL: @foo1_or_signbit_lshr(
 ; CHECK-NEXT:    [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
-; CHECK-NEXT:    [[T4:%.*]] = lshr i32 -2147483648, [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = lshr exact i32 -2147483648, [[C2:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T]], [[T4]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
 ; CHECK-NEXT:    [[OR:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]]
@@ -411,7 +411,7 @@ define i1 @foo1_or_signbit_lshr(i32 %k, i32 %c1, i32 %c2) {
 define i1 @foo1_or_signbit_lshr_logical(i32 %k, i32 %c1, i32 %c2) {
 ; CHECK-LABEL: @foo1_or_signbit_lshr_logical(
 ; CHECK-NEXT:    [[T:%.*]] = shl nuw i32 1, [[C1:%.*]]
-; CHECK-NEXT:    [[T4:%.*]] = lshr i32 -2147483648, [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = lshr exact i32 -2147483648, [[C2:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = freeze i32 [[T4]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[T]], [[TMP1]]
 ; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], [[K:%.*]]
@@ -431,7 +431,7 @@ define i1 @foo1_or_signbit_lshr_logical(i32 %k, i32 %c1, i32 %c2) {
 define <2 x i1> @foo1_or_signbit_lshr_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
 ; CHECK-LABEL: @foo1_or_signbit_lshr_vector(
 ; CHECK-NEXT:    [[T:%.*]] = shl nuw <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
-; CHECK-NEXT:    [[T4:%.*]] = lshr <2 x i32> <i32 -2147483648, i32 -2147483648>, [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = lshr exact <2 x i32> <i32 -2147483648, i32 -2147483648>, [[C2:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[T]], [[T4]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[K:%.*]]
 ; CHECK-NEXT:    [[OR:%.*]] = icmp eq <2 x i32> [[TMP2]], [[TMP1]]
diff --git a/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-b.ll b/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-b.ll
index 3edefcdd99d2f03..f0c2f129e3df3e7 100644
--- a/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-b.ll
+++ b/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-b.ll
@@ -18,7 +18,7 @@ define i32 @t0_basic(i64 %x, i32 %nbits) {
 ; CHECK-LABEL: @t0_basic(
 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], -1
 ; CHECK-NEXT:    [[T1:%.*]] = zext i32 [[T0]] to i64
-; CHECK-NEXT:    [[T2:%.*]] = shl i64 -1, [[T1]]
+; CHECK-NEXT:    [[T2:%.*]] = shl nsw i64 -1, [[T1]]
 ; CHECK-NEXT:    [[T3:%.*]] = xor i64 [[T2]], -1
 ; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
@@ -58,7 +58,7 @@ define <8 x i32> @t1_vec_splat(<8 x i64> %x, <8 x i32> %nbits) {
 ; CHECK-LABEL: @t1_vec_splat(
 ; CHECK-NEXT:    [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
 ; CHECK-NEXT:    [[T1:%.*]] = zext <8 x i32> [[T0]] to <8 x i64>
-; CHECK-NEXT:    [[T2:%.*]] = shl <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>, [[T1]]
+; CHECK-NEXT:    [[T2:%.*]] = shl nsw <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>, [[T1]]
 ; CHECK-NEXT:    [[T3:%.*]] = xor <8 x i64> [[T2]], <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>
 ; CHECK-NEXT:    [[T4:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, [[NBITS]]
 ; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T0]])
@@ -128,7 +128,7 @@ define <8 x i32> @t3_vec_nonsplat(<8 x i64> %x, <8 x i32> %nbits) {
 ; CHECK-LABEL: @t3_vec_nonsplat(
 ; CHECK-NEXT:    [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -33, i32 -32, i32 -31, i32 -1, i32 0, i32 1, i32 31, i32 32>
 ; CHECK-NEXT:    [[T1:%.*]] = zext <8 x i32> [[T0]] to <8 x i64>
-; CHECK-NEXT:    [[T2:%.*]] = shl <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>, [[T1]]
+; CHECK-NEXT:    [[T2:%.*]] = shl nsw <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>, [[T1]]
 ; CHECK-NEXT:    [[T3:%.*]] = xor <8 x i64> [[T2]], <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>
 ; CHECK-NEXT:    [[T4:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, [[NBITS]]
 ; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T0]])
@@ -165,7 +165,7 @@ define i32 @t4_allones_trunc(i64 %x, i32 %nbits) {
 ; CHECK-LABEL: @t4_allones_trunc(
 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], -1
 ; CHECK-NEXT:    [[T1:%.*]] = zext i32 [[T0]] to i64
-; CHECK-NEXT:    [[T2:%.*]] = shl i64 -1, [[T1]]
+; CHECK-NEXT:    [[T2:%.*]] = shl nsw i64 -1, [[T1]]
 ; CHECK-NEXT:    [[T3:%.*]] = xor i64 [[T2]], 4294967295
 ; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
@@ -202,7 +202,7 @@ define i32 @n5_extrause0(i64 %x, i32 %nbits) {
 ; CHECK-LABEL: @n5_extrause0(
 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], -1
 ; CHECK-NEXT:    [[T1:%.*]] = zext i32 [[T0]] to i64
-; CHECK-NEXT:    [[T2:%.*]] = shl i64 -1, [[T1]]
+; CHECK-NEXT:    [[T2:%.*]] = shl nsw i64 -1, [[T1]]
 ; CHECK-NEXT:    [[T3:%.*]] = xor i64 [[T2]], -1
 ; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
@@ -238,7 +238,7 @@ define i32 @n6_extrause1(i64 %x, i32 %nbits) {
 ; CHECK-LABEL: @n6_extrause1(
 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], -1
 ; CHECK-NEXT:    [[T1:%.*]] = zext i32 [[T0]] to i64
-; CHECK-NEXT:    [[T2:%.*]] = shl i64 -1, [[T1]]
+; CHECK-NEXT:    [[T2:%.*]] = shl nsw i64 -1, [[T1]]
 ; CHECK-NEXT:    [[T3:%.*]] = xor i64 [[T2]], -1
 ; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
@@ -274,7 +274,7 @@ define i32 @n7_extrause2(i64 %x, i32 %nbits) {
 ; CHECK-LABEL: @n7_extrause2(
 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], -1
 ; CHECK-NEXT:    [[T1:%.*]] = zext i32 [[T0]] to i64
-; CHECK-NEXT:    [[T2:%.*]] = shl i64 -1, [[T1]]
+; CHECK-NEXT:    [[T2:%.*]] = shl nsw i64 -1, [[T1]]
 ; CHECK-NEXT:    [[T3:%.*]] = xor i64 [[T2]], -1
 ; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
diff --git a/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-d.ll b/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-d.ll
index 86af88de08e2cb0..6b7061ff9bd0640 100644
--- a/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-d.ll
+++ b/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-after-truncation-variant-d.ll
@@ -17,7 +17,7 @@ declare void @use64(i64)
 define i32 @t0_basic(i64 %x, i32 %nbits) {
 ; CHECK-LABEL: @t0_basic(
 ; CHECK-NEXT:    [[T0:%.*]] = zext i32 [[NBITS:%.*]] to i64
-; CHECK-NEXT:    [[T1:%.*]] = shl i64 -1, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw i64 -1, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = lshr exact i64 [[T1]], [[T0]]
 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[NBITS]], -33
 ; CHECK-NEXT:    call void @use64(i64 [[T0]])
@@ -53,7 +53,7 @@ declare void @use8xi64(<8 x i64>)
 define <8 x i32> @t1_vec_splat(<8 x i64> %x, <8 x i32> %nbits) {
 ; CHECK-LABEL: @t1_vec_splat(
 ; CHECK-NEXT:    [[T0:%.*]] = zext <8 x i32> [[NBITS:%.*]] to <8 x i64>
-; CHECK-NEXT:    [[T1:%.*]] = shl <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = lshr exact <8 x i64> [[T1]], [[T0]]
 ; CHECK-NEXT:    [[T3:%.*]] = add <8 x i32> [[NBITS]], <i32 -33, i32 -33, i32 -33, i32 -33, i32 -33, i32 -33, i32 -33, i32 -33>
 ; CHECK-NEXT:    call void @use8xi64(<8 x i64> [[T0]])
@@ -148,7 +148,7 @@ define <8 x i32> @t3_vec_nonsplat(<8 x i64> %x, <8 x i32> %nbits) {
 define i32 @n4_extrause0(i64 %x, i32 %nbits) {
 ; CHECK-LABEL: @n4_extrause0(
 ; CHECK-NEXT:    [[T0:%.*]] = zext i32 [[NBITS:%.*]] to i64
-; CHECK-NEXT:    [[T1:%.*]] = shl i64 -1, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw i64 -1, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = lshr exact i64 [[T1]], [[T0]]
 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[NBITS]], -33
 ; CHECK-NEXT:    call void @use64(i64 [[T0]])
@@ -181,7 +181,7 @@ define i32 @n4_extrause0(i64 %x, i32 %nbits) {
 define i32 @n5_extrause1(i64 %x, i32 %nbits) {
 ; CHECK-LABEL: @n5_extrause1(
 ; CHECK-NEXT:    [[T0:%.*]] = zext i32 [[NBITS:%.*]] to i64
-; CHECK-NEXT:    [[T1:%.*]] = shl i64 -1, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw i64 -1, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = lshr exact i64 [[T1]], [[T0]]
 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[NBITS]], -33
 ; CHECK-NEXT:    call void @use64(i64 [[T0]])
@@ -214,7 +214,7 @@ define i32 @n5_extrause1(i64 %x, i32 %nbits) {
 define i32 @n6_extrause2(i64 %x, i32 %nbits) {
 ; CHECK-LABEL: @n6_extrause2(
 ; CHECK-NEXT:    [[T0:%.*]] = zext i32 [[NBITS:%.*]] to i64
-; CHECK-NEXT:    [[T1:%.*]] = shl i64 -1, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw i64 -1, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = lshr exact i64 [[T1]], [[T0]]
 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[NBITS]], -33
 ; CHECK-NEXT:    call void @use64(i64 [[T0]])
diff --git a/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-b.ll b/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-b.ll
index 8acb9834d3b8871..8b3f01bcb76913f 100644
--- a/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-b.ll
+++ b/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-b.ll
@@ -16,7 +16,7 @@ declare void @use32(i32)
 define i32 @t0_basic(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @t0_basic(
 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], -1
-; CHECK-NEXT:    [[T1:%.*]] = shl i32 -1, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw i32 -1, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = xor i32 [[T1]], -1
 ; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
@@ -47,7 +47,7 @@ declare void @use8xi32(<8 x i32>)
 define <8 x i32> @t1_vec_splat(<8 x i32> %x, <8 x i32> %nbits) {
 ; CHECK-LABEL: @t1_vec_splat(
 ; CHECK-NEXT:    [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
-; CHECK-NEXT:    [[T1:%.*]] = shl <8 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw <8 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = xor <8 x i32> [[T1]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
 ; CHECK-NEXT:    [[T4:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, [[NBITS]]
 ; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T0]])
@@ -101,7 +101,7 @@ define <8 x i32> @t1_vec_splat_undef(<8 x i32> %x, <8 x i32> %nbits) {
 define <8 x i32> @t2_vec_nonsplat(<8 x i32> %x, <8 x i32> %nbits) {
 ; CHECK-LABEL: @t2_vec_nonsplat(
 ; CHECK-NEXT:    [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -33, i32 -32, i32 -31, i32 -1, i32 0, i32 1, i32 31, i32 32>
-; CHECK-NEXT:    [[T1:%.*]] = shl <8 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw <8 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = xor <8 x i32> [[T1]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
 ; CHECK-NEXT:    [[T4:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, [[NBITS]]
 ; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T0]])
@@ -130,7 +130,7 @@ define <8 x i32> @t2_vec_nonsplat(<8 x i32> %x, <8 x i32> %nbits) {
 define i32 @n3_extrause(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @n3_extrause(
 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], -1
-; CHECK-NEXT:    [[T1:%.*]] = shl i32 -1, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw i32 -1, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = xor i32 [[T1]], -1
 ; CHECK-NEXT:    [[T3:%.*]] = and i32 [[T2]], [[X:%.*]]
 ; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]
diff --git a/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-d.ll b/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-d.ll
index 2031001404925e8..92805c620683c00 100644
--- a/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-d.ll
+++ b/llvm/test/Transforms/InstCombine/partally-redundant-left-shift-input-masking-variant-d.ll
@@ -15,7 +15,7 @@ declare void @use32(i32)
 
 define i32 @t0_basic(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @t0_basic(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i32 [[T0]], [[NBITS]]
 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[NBITS]], -1
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
@@ -42,7 +42,7 @@ declare void @use8xi32(<8 x i32>)
 
 define <8 x i32> @t2_vec_splat(<8 x i32> %x, <8 x i32> %nbits) {
 ; CHECK-LABEL: @t2_vec_splat(
-; CHECK-NEXT:    [[T0:%.*]] = shl <8 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw <8 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact <8 x i32> [[T0]], [[NBITS]]
 ; CHECK-NEXT:    [[T3:%.*]] = add <8 x i32> [[NBITS]], <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
 ; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T0]])
@@ -88,7 +88,7 @@ define <8 x i32> @t2_vec_splat_undef(<8 x i32> %x, <8 x i32> %nbits) {
 
 define <8 x i32> @t2_vec_nonsplat(<8 x i32> %x, <8 x i32> %nbits) {
 ; CHECK-LABEL: @t2_vec_nonsplat(
-; CHECK-NEXT:    [[T0:%.*]] = shl <8 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw <8 x i32> <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact <8 x i32> [[T0]], [[NBITS]]
 ; CHECK-NEXT:    [[T3:%.*]] = add <8 x i32> [[NBITS]], <i32 -32, i32 -31, i32 -1, i32 0, i32 1, i32 31, i32 32, i32 33>
 ; CHECK-NEXT:    call void @use8xi32(<8 x i32> [[T0]])
@@ -113,7 +113,7 @@ define <8 x i32> @t2_vec_nonsplat(<8 x i32> %x, <8 x i32> %nbits) {
 
 define i32 @n3_extrause(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @n3_extrause(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i32 [[T0]], [[NBITS]]
 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[NBITS]], -1
diff --git a/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-after-truncation-variant-b.ll b/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-after-truncation-variant-b.ll
index 56aa6cd591a0bac..d49cfe990d82d9d 100644
--- a/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-after-truncation-variant-b.ll
+++ b/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-after-truncation-variant-b.ll
@@ -17,7 +17,7 @@ declare void @use64(i64)
 define i32 @t0_basic(i64 %x, i32 %nbits) {
 ; CHECK-LABEL: @t0_basic(
 ; CHECK-NEXT:    [[T0:%.*]] = zext i32 [[NBITS:%.*]] to i64
-; CHECK-NEXT:    [[T1:%.*]] = shl i64 -1, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw i64 -1, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = xor i64 [[T1]], -1
 ; CHECK-NEXT:    [[T3:%.*]] = sub i32 32, [[NBITS]]
 ; CHECK-NEXT:    [[T4:%.*]] = and i64 [[T2]], [[X:%.*]]
@@ -57,7 +57,7 @@ declare void @use8xi64(<8 x i64>)
 define <8 x i32> @t1_vec_splat(<8 x i64> %x, <8 x i32> %nbits) {
 ; CHECK-LABEL: @t1_vec_splat(
 ; CHECK-NEXT:    [[T0:%.*]] = zext <8 x i32> [[NBITS:%.*]] to <8 x i64>
-; CHECK-NEXT:    [[T1:%.*]] = shl <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = xor <8 x i64> [[T1]], <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>
 ; CHECK-NEXT:    [[T3:%.*]] = sub <8 x i32> <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>, [[NBITS]]
 ; CHECK-NEXT:    [[T4:%.*]] = and <8 x i64> [[T2]], [[X:%.*]]
@@ -128,7 +128,7 @@ define <8 x i32> @t3_vec_nonsplat(<8 x i64> %x, <8 x i32> %nbits) {
 ; CHECK-LABEL: @t3_vec_nonsplat(
 ; CHECK-NEXT:    [[T0:%.*]] = add <8 x i32> [[NBITS:%.*]], <i32 -1, i32 0, i32 0, i32 1, i32 0, i32 0, i32 0, i32 0>
 ; CHECK-NEXT:    [[T1:%.*]] = zext <8 x i32> [[T0]] to <8 x i64>
-; CHECK-NEXT:    [[T2:%.*]] = shl <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>, [[T1]]
+; CHECK-NEXT:    [[T2:%.*]] = shl nsw <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>, [[T1]]
 ; CHECK-NEXT:    [[T3:%.*]] = xor <8 x i64> [[T2]], <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>
 ; CHECK-NEXT:    [[T4:%.*]] = sub <8 x i32> <i32 33, i32 32, i32 33, i32 32, i32 32, i32 32, i32 32, i32 32>, [[NBITS]]
 ; CHECK-NEXT:    [[T5:%.*]] = and <8 x i64> [[T3]], [[X:%.*]]
@@ -166,7 +166,7 @@ define <8 x i32> @t3_vec_nonsplat(<8 x i64> %x, <8 x i32> %nbits) {
 define i32 @t4_allones_trunc(i64 %x, i32 %nbits) {
 ; CHECK-LABEL: @t4_allones_trunc(
 ; CHECK-NEXT:    [[T0:%.*]] = zext i32 [[NBITS:%.*]] to i64
-; CHECK-NEXT:    [[T1:%.*]] = shl i64 -1, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw i64 -1, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = xor i64 [[T1]], 4294967295
 ; CHECK-NEXT:    [[T3:%.*]] = sub i32 32, [[NBITS]]
 ; CHECK-NEXT:    [[T4:%.*]] = and i64 [[T2]], [[X:%.*]]
@@ -203,7 +203,7 @@ define i32 @t4_allones_trunc(i64 %x, i32 %nbits) {
 define i32 @n5_extrause(i64 %x, i32 %nbits) {
 ; CHECK-LABEL: @n5_extrause(
 ; CHECK-NEXT:    [[T0:%.*]] = zext i32 [[NBITS:%.*]] to i64
-; CHECK-NEXT:    [[T1:%.*]] = shl i64 -1, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw i64 -1, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = xor i64 [[T1]], -1
 ; CHECK-NEXT:    [[T3:%.*]] = sub i32 32, [[NBITS]]
 ; CHECK-NEXT:    [[T4:%.*]] = and i64 [[T2]], [[X:%.*]]
diff --git a/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-after-truncation-variant-d.ll b/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-after-truncation-variant-d.ll
index 6ee69c09cd06127..bdc7bebf00ecac6 100644
--- a/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-after-truncation-variant-d.ll
+++ b/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-after-truncation-variant-d.ll
@@ -17,7 +17,7 @@ declare void @use64(i64)
 define i32 @t0_basic(i64 %x, i32 %nbits) {
 ; CHECK-LABEL: @t0_basic(
 ; CHECK-NEXT:    [[T0:%.*]] = zext i32 [[NBITS:%.*]] to i64
-; CHECK-NEXT:    [[T1:%.*]] = shl i64 -1, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw i64 -1, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = lshr exact i64 [[T1]], [[T0]]
 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[NBITS]], -32
 ; CHECK-NEXT:    [[T4:%.*]] = and i64 [[T2]], [[X:%.*]]
@@ -55,7 +55,7 @@ declare void @use8xi64(<8 x i64>)
 define <8 x i32> @t1_vec_splat(<8 x i64> %x, <8 x i32> %nbits) {
 ; CHECK-LABEL: @t1_vec_splat(
 ; CHECK-NEXT:    [[T0:%.*]] = zext <8 x i32> [[NBITS:%.*]] to <8 x i64>
-; CHECK-NEXT:    [[T1:%.*]] = shl <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw <8 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = lshr exact <8 x i64> [[T1]], [[T0]]
 ; CHECK-NEXT:    [[T3:%.*]] = add <8 x i32> [[NBITS]], <i32 -32, i32 -32, i32 -32, i32 -32, i32 -32, i32 -32, i32 -32, i32 -32>
 ; CHECK-NEXT:    [[T4:%.*]] = and <8 x i64> [[T2]], [[X:%.*]]
@@ -156,7 +156,7 @@ define <8 x i32> @t3_vec_nonsplat(<8 x i64> %x, <8 x i32> %nbits) {
 define i32 @n4_extrause(i64 %x, i32 %nbits) {
 ; CHECK-LABEL: @n4_extrause(
 ; CHECK-NEXT:    [[T0:%.*]] = zext i32 [[NBITS:%.*]] to i64
-; CHECK-NEXT:    [[T1:%.*]] = shl i64 -1, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw i64 -1, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = lshr exact i64 [[T1]], [[T0]]
 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[NBITS]], -32
 ; CHECK-NEXT:    [[T4:%.*]] = and i64 [[T2]], [[X:%.*]]
diff --git a/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-variant-b.ll b/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-variant-b.ll
index aef92a481b6d236..ddaef5f4b47c81e 100644
--- a/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-variant-b.ll
+++ b/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-variant-b.ll
@@ -17,7 +17,7 @@ declare void @use32(i32)
 
 define i32 @t0_basic(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @t0_basic(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i32 [[T0]], -1
 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    [[T3:%.*]] = sub i32 32, [[NBITS]]
@@ -42,7 +42,7 @@ define i32 @t0_basic(i32 %x, i32 %nbits) {
 
 define i32 @t1_bigger_shift(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @t1_bigger_shift(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i32 [[T0]], -1
 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    [[T3:%.*]] = sub i32 33, [[NBITS]]
@@ -68,7 +68,7 @@ define i32 @t1_bigger_shift(i32 %x, i32 %nbits) {
 define i32 @t2_bigger_mask(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @t2_bigger_mask(
 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[NBITS:%.*]], 1
-; CHECK-NEXT:    [[T1:%.*]] = shl i32 -1, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw i32 -1, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = xor i32 [[T1]], -1
 ; CHECK-NEXT:    [[T3:%.*]] = and i32 [[T2]], [[X:%.*]]
 ; CHECK-NEXT:    [[T4:%.*]] = sub i32 32, [[NBITS]]
@@ -100,7 +100,7 @@ declare void @use3xi32(<3 x i32>)
 
 define <3 x i32> @t3_vec_splat(<3 x i32> %x, <3 x i32> %nbits) {
 ; CHECK-LABEL: @t3_vec_splat(
-; CHECK-NEXT:    [[T1:%.*]] = shl <3 x i32> <i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw <3 x i32> <i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T2:%.*]] = xor <3 x i32> [[T1]], <i32 -1, i32 -1, i32 -1>
 ; CHECK-NEXT:    [[T3:%.*]] = and <3 x i32> [[T2]], [[X:%.*]]
 ; CHECK-NEXT:    [[T4:%.*]] = sub <3 x i32> <i32 32, i32 32, i32 32>, [[NBITS]]
@@ -129,7 +129,7 @@ define <3 x i32> @t3_vec_splat(<3 x i32> %x, <3 x i32> %nbits) {
 define <3 x i32> @t4_vec_nonsplat(<3 x i32> %x, <3 x i32> %nbits) {
 ; CHECK-LABEL: @t4_vec_nonsplat(
 ; CHECK-NEXT:    [[T0:%.*]] = add <3 x i32> [[NBITS:%.*]], <i32 -1, i32 0, i32 1>
-; CHECK-NEXT:    [[T1:%.*]] = shl <3 x i32> <i32 -1, i32 -1, i32 -1>, [[T0]]
+; CHECK-NEXT:    [[T1:%.*]] = shl nsw <3 x i32> <i32 -1, i32 -1, i32 -1>, [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = xor <3 x i32> [[T1]], <i32 -1, i32 -1, i32 -1>
 ; CHECK-NEXT:    [[T3:%.*]] = and <3 x i32> [[T2]], [[X:%.*]]
 ; CHECK-NEXT:    [[T4:%.*]] = sub <3 x i32> <i32 33, i32 32, i32 32>, [[NBITS]]
@@ -190,7 +190,7 @@ declare i32 @gen32()
 define i32 @t6_commutativity0(i32 %nbits) {
 ; CHECK-LABEL: @t6_commutativity0(
 ; CHECK-NEXT:    [[X:%.*]] = call i32 @gen32()
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i32 [[T0]], -1
 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[X]], [[T1]]
 ; CHECK-NEXT:    [[T3:%.*]] = sub i32 32, [[NBITS]]
@@ -216,9 +216,9 @@ define i32 @t6_commutativity0(i32 %nbits) {
 
 define i32 @t7_commutativity1(i32 %nbits0, i32 %nbits1) {
 ; CHECK-LABEL: @t7_commutativity1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS0:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS0:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i32 [[T0]], -1
-; CHECK-NEXT:    [[T2:%.*]] = shl i32 -1, [[NBITS1:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = shl nsw i32 -1, [[NBITS1:%.*]]
 ; CHECK-NEXT:    [[T3:%.*]] = xor i32 [[T2]], -1
 ; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T3]], [[T1]]
 ; CHECK-NEXT:    [[T5:%.*]] = sub i32 32, [[NBITS0]]
@@ -248,9 +248,9 @@ define i32 @t7_commutativity1(i32 %nbits0, i32 %nbits1) {
 }
 define i32 @t8_commutativity2(i32 %nbits0, i32 %nbits1) {
 ; CHECK-LABEL: @t8_commutativity2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS0:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS0:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i32 [[T0]], -1
-; CHECK-NEXT:    [[T2:%.*]] = shl i32 -1, [[NBITS1:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = shl nsw i32 -1, [[NBITS1:%.*]]
 ; CHECK-NEXT:    [[T3:%.*]] = xor i32 [[T2]], -1
 ; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T3]], [[T1]]
 ; CHECK-NEXT:    [[T5:%.*]] = sub i32 32, [[NBITS1]]
@@ -283,7 +283,7 @@ define i32 @t8_commutativity2(i32 %nbits0, i32 %nbits1) {
 
 define i32 @t9_nuw(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @t9_nuw(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i32 [[T0]], -1
 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    [[T3:%.*]] = sub i32 32, [[NBITS]]
@@ -308,7 +308,7 @@ define i32 @t9_nuw(i32 %x, i32 %nbits) {
 
 define i32 @t10_nsw(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @t10_nsw(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i32 [[T0]], -1
 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    [[T3:%.*]] = sub i32 32, [[NBITS]]
@@ -333,7 +333,7 @@ define i32 @t10_nsw(i32 %x, i32 %nbits) {
 
 define i32 @t11_nuw_nsw(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @t11_nuw_nsw(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = xor i32 [[T0]], -1
 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    [[T3:%.*]] = sub i32 32, [[NBITS]]
diff --git a/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-variant-d.ll b/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-variant-d.ll
index ab0aa07aba8bf8d..c91e5a0cc577c81 100644
--- a/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-variant-d.ll
+++ b/llvm/test/Transforms/InstCombine/redundant-left-shift-input-masking-variant-d.ll
@@ -17,7 +17,7 @@ declare void @use32(i32)
 
 define i32 @t0_basic(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @t0_basic(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i32 [[T0]], [[NBITS]]
 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
@@ -38,7 +38,7 @@ define i32 @t0_basic(i32 %x, i32 %nbits) {
 
 define i32 @t1_bigger_shift(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @t1_bigger_shift(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i32 [[T0]], [[NBITS]]
 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[NBITS]], 1
@@ -67,7 +67,7 @@ declare void @use3xi32(<3 x i32>)
 
 define <3 x i32> @t2_vec_splat(<3 x i32> %x, <3 x i32> %nbits) {
 ; CHECK-LABEL: @t2_vec_splat(
-; CHECK-NEXT:    [[T0:%.*]] = shl <3 x i32> <i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw <3 x i32> <i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact <3 x i32> [[T0]], [[NBITS]]
 ; CHECK-NEXT:    [[T2:%.*]] = and <3 x i32> [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    [[T3:%.*]] = add <3 x i32> [[NBITS]], <i32 1, i32 1, i32 1>
@@ -92,7 +92,7 @@ define <3 x i32> @t2_vec_splat(<3 x i32> %x, <3 x i32> %nbits) {
 
 define <3 x i32> @t3_vec_nonsplat(<3 x i32> %x, <3 x i32> %nbits) {
 ; CHECK-LABEL: @t3_vec_nonsplat(
-; CHECK-NEXT:    [[T0:%.*]] = shl <3 x i32> <i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw <3 x i32> <i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact <3 x i32> [[T0]], [[NBITS]]
 ; CHECK-NEXT:    [[T2:%.*]] = and <3 x i32> [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    [[T3:%.*]] = add <3 x i32> [[NBITS]], <i32 1, i32 0, i32 2>
@@ -146,7 +146,7 @@ declare i32 @gen32()
 define i32 @t5_commutativity0(i32 %nbits) {
 ; CHECK-LABEL: @t5_commutativity0(
 ; CHECK-NEXT:    [[X:%.*]] = call i32 @gen32()
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i32 [[T0]], [[NBITS]]
 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[X]], [[T1]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
@@ -168,9 +168,9 @@ define i32 @t5_commutativity0(i32 %nbits) {
 
 define i32 @t6_commutativity1(i32 %nbits0, i32 %nbits1) {
 ; CHECK-LABEL: @t6_commutativity1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS0:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS0:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i32 [[T0]], [[NBITS0]]
-; CHECK-NEXT:    [[T2:%.*]] = shl i32 -1, [[NBITS1:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = shl nsw i32 -1, [[NBITS1:%.*]]
 ; CHECK-NEXT:    [[T3:%.*]] = lshr i32 [[T0]], [[NBITS1]]
 ; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T3]], [[T1]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
@@ -196,9 +196,9 @@ define i32 @t6_commutativity1(i32 %nbits0, i32 %nbits1) {
 }
 define i32 @t7_commutativity2(i32 %nbits0, i32 %nbits1) {
 ; CHECK-LABEL: @t7_commutativity2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS0:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS0:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i32 [[T0]], [[NBITS0]]
-; CHECK-NEXT:    [[T2:%.*]] = shl i32 -1, [[NBITS1:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = shl nsw i32 -1, [[NBITS1:%.*]]
 ; CHECK-NEXT:    [[T3:%.*]] = lshr i32 [[T0]], [[NBITS1]]
 ; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T3]], [[T1]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
@@ -227,7 +227,7 @@ define i32 @t7_commutativity2(i32 %nbits0, i32 %nbits1) {
 
 define i32 @t8_nuw(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @t8_nuw(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i32 [[T0]], [[NBITS]]
 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
@@ -248,7 +248,7 @@ define i32 @t8_nuw(i32 %x, i32 %nbits) {
 
 define i32 @t9_nsw(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @t9_nsw(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i32 [[T0]], [[NBITS]]
 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
@@ -269,7 +269,7 @@ define i32 @t9_nsw(i32 %x, i32 %nbits) {
 
 define i32 @t10_nuw_nsw(i32 %x, i32 %nbits) {
 ; CHECK-LABEL: @t10_nuw_nsw(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i32 [[T0]], [[NBITS]]
 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
@@ -297,7 +297,7 @@ define i32 @t11_assume_uge(i32 %x, i32 %masknbits, i32 %shiftnbits) {
 ; CHECK-LABEL: @t11_assume_uge(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[SHIFTNBITS:%.*]], [[MASKNBITS:%.*]]
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[MASKNBITS]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[MASKNBITS]]
 ; CHECK-NEXT:    [[T1:%.*]] = lshr exact i32 [[T0]], [[MASKNBITS]]
 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[X:%.*]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
diff --git a/llvm/test/Transforms/InstCombine/redundant-right-shift-input-masking.ll b/llvm/test/Transforms/InstCombine/redundant-right-shift-input-masking.ll
index 914f1906d26863e..45880ac5efe51e7 100644
--- a/llvm/test/Transforms/InstCombine/redundant-right-shift-input-masking.ll
+++ b/llvm/test/Transforms/InstCombine/redundant-right-shift-input-masking.ll
@@ -12,7 +12,7 @@
 
 define i32 @t0_lshr(i32 %data, i32 %nbits) {
 ; CHECK-LABEL: @t0_lshr(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[DATA:%.*]]
 ; CHECK-NEXT:    [[T2:%.*]] = lshr exact i32 [[T1]], [[NBITS]]
 ; CHECK-NEXT:    ret i32 [[T2]]
@@ -24,7 +24,7 @@ define i32 @t0_lshr(i32 %data, i32 %nbits) {
 }
 define i32 @t1_sshr(i32 %data, i32 %nbits) {
 ; CHECK-LABEL: @t1_sshr(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[DATA:%.*]]
 ; CHECK-NEXT:    [[T2:%.*]] = ashr exact i32 [[T1]], [[NBITS]]
 ; CHECK-NEXT:    ret i32 [[T2]]
@@ -39,7 +39,7 @@ define i32 @t1_sshr(i32 %data, i32 %nbits) {
 
 define <4 x i32> @t2_vec(<4 x i32> %data, <4 x i32> %nbits) {
 ; CHECK-LABEL: @t2_vec(
-; CHECK-NEXT:    [[T0:%.*]] = shl <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = and <4 x i32> [[T0]], [[DATA:%.*]]
 ; CHECK-NEXT:    [[T2:%.*]] = lshr <4 x i32> [[T1]], [[NBITS]]
 ; CHECK-NEXT:    ret <4 x i32> [[T2]]
@@ -69,7 +69,7 @@ declare void @use32(i32)
 
 define i32 @t4_extrause0(i32 %data, i32 %nbits) {
 ; CHECK-LABEL: @t4_extrause0(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[DATA:%.*]]
 ; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[T1]], [[NBITS]]
@@ -84,7 +84,7 @@ define i32 @t4_extrause0(i32 %data, i32 %nbits) {
 
 define i32 @t5_extrause1(i32 %data, i32 %nbits) {
 ; CHECK-LABEL: @t5_extrause1(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[DATA:%.*]]
 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
 ; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[T1]], [[NBITS]]
@@ -99,7 +99,7 @@ define i32 @t5_extrause1(i32 %data, i32 %nbits) {
 
 define i32 @t6_extrause2(i32 %data, i32 %nbits) {
 ; CHECK-LABEL: @t6_extrause2(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[DATA:%.*]]
 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
@@ -191,7 +191,7 @@ declare i32 @gen32()
 define i32 @t11_commutative(i32 %nbits) {
 ; CHECK-LABEL: @t11_commutative(
 ; CHECK-NEXT:    [[DATA:%.*]] = call i32 @gen32()
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[DATA]], [[T0]]
 ; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[T1]], [[NBITS]]
 ; CHECK-NEXT:    ret i32 [[T2]]
@@ -220,7 +220,7 @@ define i32 @n12(i32 %data, i32 %nbits) {
 
 define i32 @n13(i32 %data, i32 %nbits0, i32 %nbits1) {
 ; CHECK-LABEL: @n13(
-; CHECK-NEXT:    [[T0:%.*]] = shl i32 -1, [[NBITS0:%.*]]
+; CHECK-NEXT:    [[T0:%.*]] = shl nsw i32 -1, [[NBITS0:%.*]]
 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[DATA:%.*]]
 ; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[T1]], [[NBITS1:%.*]]
 ; CHECK-NEXT:    ret i32 [[T2]]
diff --git a/llvm/test/Transforms/InstCombine/shift-shift.ll b/llvm/test/Transforms/InstCombine/shift-shift.ll
index 4270a2c2ba205ed..ad25160d10c8a64 100644
--- a/llvm/test/Transforms/InstCombine/shift-shift.ll
+++ b/llvm/test/Transforms/InstCombine/shift-shift.ll
@@ -531,7 +531,7 @@ define <2 x i6> @shl_lshr_demand5_undef_right(<2 x i8> %x) {
 define <2 x i6> @shl_lshr_demand5_nonuniform_vec_left(<2 x i8> %x) {
 ; CHECK-LABEL: @shl_lshr_demand5_nonuniform_vec_left(
 ; CHECK-NEXT:    [[SHL:%.*]] = shl <2 x i8> <i8 -108, i8 -108>, [[X:%.*]]
-; CHECK-NEXT:    [[LSHR:%.*]] = lshr <2 x i8> [[SHL]], <i8 1, i8 2>
+; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact <2 x i8> [[SHL]], <i8 1, i8 2>
 ; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i8> [[LSHR]] to <2 x i6>
 ; CHECK-NEXT:    ret <2 x i6> [[R]]
 ;
@@ -694,7 +694,7 @@ define <2 x i8> @lshr_shl_demand5_undef_right(<2 x i8> %x) {
 define <2 x i8> @lshr_shl_demand5_nonuniform_vec_left(<2 x i8> %x) {
 ; CHECK-LABEL: @lshr_shl_demand5_nonuniform_vec_left(
 ; CHECK-NEXT:    [[SHR:%.*]] = lshr <2 x i8> <i8 45, i8 45>, [[X:%.*]]
-; CHECK-NEXT:    [[SHL:%.*]] = shl <2 x i8> [[SHR]], <i8 1, i8 2>
+; CHECK-NEXT:    [[SHL:%.*]] = shl nuw <2 x i8> [[SHR]], <i8 1, i8 2>
 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i8> [[SHL]], <i8 108, i8 108>
 ; CHECK-NEXT:    ret <2 x i8> [[R]]
 ;
diff --git a/llvm/test/Transforms/InstCombine/shift.ll b/llvm/test/Transforms/InstCombine/shift.ll
index e928d99d2feb127..8c785c3734cfb99 100644
--- a/llvm/test/Transforms/InstCombine/shift.ll
+++ b/llvm/test/Transforms/InstCombine/shift.ll
@@ -1235,7 +1235,7 @@ define <2 x i32> @test_shl_zext_bool_vec(<2 x i1> %t) {
 define i32 @test_shl_zext_bool_not_constant(i1 %cmp, i32 %shamt) {
 ; CHECK-LABEL: @test_shl_zext_bool_not_constant(
 ; CHECK-NEXT:    [[CONV3:%.*]] = zext i1 [[CMP:%.*]] to i32
-; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[CONV3]], [[SHAMT:%.*]]
+; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 [[CONV3]], [[SHAMT:%.*]]
 ; CHECK-NEXT:    ret i32 [[SHL]]
 ;
   %conv3 = zext i1 %cmp to i32
diff --git a/llvm/test/Transforms/InstCombine/shl-sub.ll b/llvm/test/Transforms/InstCombine/shl-sub.ll
index 332c748e775ed77..962cf0562ae4e4e 100644
--- a/llvm/test/Transforms/InstCombine/shl-sub.ll
+++ b/llvm/test/Transforms/InstCombine/shl-sub.ll
@@ -5,7 +5,7 @@ declare void @use(i32)
 
 define i32 @shl_sub_i32(i32 %x) {
 ; CHECK-LABEL: @shl_sub_i32(
-; CHECK-NEXT:    [[R:%.*]] = lshr i32 -2147483648, [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = lshr exact i32 -2147483648, [[X:%.*]]
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %s = sub i32 31, %x
@@ -17,7 +17,7 @@ define i32 @shl_sub_multiuse_i32(i32 %x) {
 ; CHECK-LABEL: @shl_sub_multiuse_i32(
 ; CHECK-NEXT:    [[S:%.*]] = sub i32 31, [[X:%.*]]
 ; CHECK-NEXT:    call void @use(i32 [[S]])
-; CHECK-NEXT:    [[R:%.*]] = lshr i32 -2147483648, [[X]]
+; CHECK-NEXT:    [[R:%.*]] = lshr exact i32 -2147483648, [[X]]
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %s = sub i32 31, %x
@@ -28,7 +28,7 @@ define i32 @shl_sub_multiuse_i32(i32 %x) {
 
 define i8 @shl_sub_i8(i8 %x) {
 ; CHECK-LABEL: @shl_sub_i8(
-; CHECK-NEXT:    [[R:%.*]] = lshr i8 -128, [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = lshr exact i8 -128, [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[R]]
 ;
   %s = sub i8 7, %x
@@ -38,7 +38,7 @@ define i8 @shl_sub_i8(i8 %x) {
 
 define i64 @shl_sub_i64(i64 %x) {
 ; CHECK-LABEL: @shl_sub_i64(
-; CHECK-NEXT:    [[R:%.*]] = lshr i64 -9223372036854775808, [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = lshr exact i64 -9223372036854775808, [[X:%.*]]
 ; CHECK-NEXT:    ret i64 [[R]]
 ;
   %s = sub i64 63, %x
@@ -48,7 +48,7 @@ define i64 @shl_sub_i64(i64 %x) {
 
 define <2 x i64> @shl_sub_i64_vec(<2 x i64> %x) {
 ; CHECK-LABEL: @shl_sub_i64_vec(
-; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i64> <i64 -9223372036854775808, i64 -9223372036854775808>, [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = lshr exact <2 x i64> <i64 -9223372036854775808, i64 -9223372036854775808>, [[X:%.*]]
 ; CHECK-NEXT:    ret <2 x i64> [[R]]
 ;
   %s = sub <2 x i64> <i64 63, i64 63>, %x
@@ -58,7 +58,7 @@ define <2 x i64> @shl_sub_i64_vec(<2 x i64> %x) {
 
 define <3 x i64> @shl_sub_i64_vec_poison(<3 x i64> %x) {
 ; CHECK-LABEL: @shl_sub_i64_vec_poison(
-; CHECK-NEXT:    [[R:%.*]] = lshr <3 x i64> <i64 -9223372036854775808, i64 -9223372036854775808, i64 -9223372036854775808>, [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = lshr exact <3 x i64> <i64 -9223372036854775808, i64 -9223372036854775808, i64 -9223372036854775808>, [[X:%.*]]
 ; CHECK-NEXT:    ret <3 x i64> [[R]]
 ;
   %s = sub <3 x i64> <i64 63, i64 63, i64 63>, %x
diff --git a/llvm/test/Transforms/InstCombine/signbit-lshr-and-icmpeq-zero.ll b/llvm/test/Transforms/InstCombine/signbit-lshr-and-icmpeq-zero.ll
index 1633ec8a89d3b07..4d8481dd759ea62 100644
--- a/llvm/test/Transforms/InstCombine/signbit-lshr-and-icmpeq-zero.ll
+++ b/llvm/test/Transforms/InstCombine/signbit-lshr-and-icmpeq-zero.ll
@@ -8,7 +8,7 @@
 
 define i1 @scalar_i8_signbit_lshr_and_eq(i8 %x, i8 %y) {
 ; CHECK-LABEL: @scalar_i8_signbit_lshr_and_eq(
-; CHECK-NEXT:    [[LSHR:%.*]] = lshr i8 -128, [[Y:%.*]]
+; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i8 -128, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[LSHR]], [[X:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[AND]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
@@ -21,7 +21,7 @@ define i1 @scalar_i8_signbit_lshr_and_eq(i8 %x, i8 %y) {
 
 define i1 @scalar_i16_signbit_lshr_and_eq(i16 %x, i16 %y) {
 ; CHECK-LABEL: @scalar_i16_signbit_lshr_and_eq(
-; CHECK-NEXT:    [[LSHR:%.*]] = lshr i16 -32768, [[Y:%.*]]
+; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i16 -32768, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i16 [[LSHR]], [[X:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i16 [[AND]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
@@ -34,7 +34,7 @@ define i1 @scalar_i16_signbit_lshr_and_eq(i16 %x, i16 %y) {
 
 define i1 @scalar_i32_signbit_lshr_and_eq(i32 %x, i32 %y) {
 ; CHECK-LABEL: @scalar_i32_signbit_lshr_and_eq(
-; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 -2147483648, [[Y:%.*]]
+; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[LSHR]], [[X:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[AND]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
@@ -47,7 +47,7 @@ define i1 @scalar_i32_signbit_lshr_and_eq(i32 %x, i32 %y) {
 
 define i1 @scalar_i64_signbit_lshr_and_eq(i64 %x, i64 %y) {
 ; CHECK-LABEL: @scalar_i64_signbit_lshr_and_eq(
-; CHECK-NEXT:    [[LSHR:%.*]] = lshr i64 -9223372036854775808, [[Y:%.*]]
+; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i64 -9223372036854775808, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[LSHR]], [[X:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i64 [[AND]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
@@ -60,7 +60,7 @@ define i1 @scalar_i64_signbit_lshr_and_eq(i64 %x, i64 %y) {
 
 define i1 @scalar_i32_signbit_lshr_and_ne(i32 %x, i32 %y) {
 ; CHECK-LABEL: @scalar_i32_signbit_lshr_and_ne(
-; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 -2147483648, [[Y:%.*]]
+; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[LSHR]], [[X:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[AND]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
@@ -75,7 +75,7 @@ define i1 @scalar_i32_signbit_lshr_and_ne(i32 %x, i32 %y) {
 
 define <4 x i1> @vec_4xi32_signbit_lshr_and_eq(<4 x i32> %x, <4 x i32> %y) {
 ; CHECK-LABEL: @vec_4xi32_signbit_lshr_and_eq(
-; CHECK-NEXT:    [[LSHR:%.*]] = lshr <4 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>, [[Y:%.*]]
+; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact <4 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and <4 x i32> [[LSHR]], [[X:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp eq <4 x i32> [[AND]], zeroinitializer
 ; CHECK-NEXT:    ret <4 x i1> [[R]]
@@ -130,7 +130,7 @@ define <4 x i1> @vec_4xi32_signbit_lshr_and_eq_undef3(<4 x i32> %x, <4 x i32> %y
 ; Fold happened
 define i1 @scalar_i32_signbit_lshr_and_eq_extra_use_lshr(i32 %x, i32 %y, i32 %z, ptr %p) {
 ; CHECK-LABEL: @scalar_i32_signbit_lshr_and_eq_extra_use_lshr(
-; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 -2147483648, [[Y:%.*]]
+; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]
 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[LSHR]], [[Z:%.*]]
 ; CHECK-NEXT:    store i32 [[XOR]], ptr [[P:%.*]], align 4
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[LSHR]], [[X:%.*]]
@@ -148,7 +148,7 @@ define i1 @scalar_i32_signbit_lshr_and_eq_extra_use_lshr(i32 %x, i32 %y, i32 %z,
 ; Not fold
 define i1 @scalar_i32_signbit_lshr_and_eq_extra_use_and(i32 %x, i32 %y, i32 %z, ptr %p) {
 ; CHECK-LABEL: @scalar_i32_signbit_lshr_and_eq_extra_use_and(
-; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 -2147483648, [[Y:%.*]]
+; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[LSHR]], [[X:%.*]]
 ; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[AND]], [[Z:%.*]]
 ; CHECK-NEXT:    store i32 [[MUL]], ptr [[P:%.*]], align 4
@@ -166,7 +166,7 @@ define i1 @scalar_i32_signbit_lshr_and_eq_extra_use_and(i32 %x, i32 %y, i32 %z,
 ; Not fold
 define i1 @scalar_i32_signbit_lshr_and_eq_extra_use_lshr_and(i32 %x, i32 %y, i32 %z, ptr %p, ptr %q) {
 ; CHECK-LABEL: @scalar_i32_signbit_lshr_and_eq_extra_use_lshr_and(
-; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 -2147483648, [[Y:%.*]]
+; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[LSHR]], [[X:%.*]]
 ; CHECK-NEXT:    store i32 [[AND]], ptr [[P:%.*]], align 4
 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[LSHR]], [[Z:%.*]]
@@ -187,7 +187,7 @@ define i1 @scalar_i32_signbit_lshr_and_eq_extra_use_lshr_and(i32 %x, i32 %y, i32
 
 define i1 @scalar_i32_signbit_lshr_and_eq_X_is_constant1(i32 %y) {
 ; CHECK-LABEL: @scalar_i32_signbit_lshr_and_eq_X_is_constant1(
-; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 -2147483648, [[Y:%.*]]
+; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[LSHR]], 12345
 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[AND]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
@@ -215,7 +215,7 @@ define i1 @scalar_i32_signbit_lshr_and_eq_X_is_constant2(i32 %y) {
 
 define i1 @scalar_i32_signbit_lshr_and_slt(i32 %x, i32 %y) {
 ; CHECK-LABEL: @scalar_i32_signbit_lshr_and_slt(
-; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 -2147483648, [[Y:%.*]]
+; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[LSHR]], [[X:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i32 [[AND]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
@@ -230,7 +230,7 @@ define i1 @scalar_i32_signbit_lshr_and_slt(i32 %x, i32 %y) {
 
 define i1 @scalar_i32_signbit_lshr_and_eq_nonzero(i32 %x, i32 %y) {
 ; CHECK-LABEL: @scalar_i32_signbit_lshr_and_eq_nonzero(
-; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 -2147483648, [[Y:%.*]]
+; CHECK-NEXT:    [[LSHR:%.*]] = lshr exact i32 -2147483648, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[LSHR]], [[X:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[AND]], 1
 ; CHECK-NEXT:    ret i1 [[R]]
diff --git a/llvm/test/Transforms/InstCombine/sub-of-negatible-inseltpoison.ll b/llvm/test/Transforms/InstCombine/sub-of-negatible-inseltpoison.ll
index 1b574e2e394e73d..d76564dd7a67edd 100644
--- a/llvm/test/Transforms/InstCombine/sub-of-negatible-inseltpoison.ll
+++ b/llvm/test/Transforms/InstCombine/sub-of-negatible-inseltpoison.ll
@@ -133,7 +133,7 @@ define i8 @t6(i8 %x, i1 %y, i8 %z) {
 }
 define i8 @t7(i8 %x, i1 %y, i8 %z) {
 ; CHECK-LABEL: @t7(
-; CHECK-NEXT:    [[T0_NEG:%.*]] = shl i8 -1, [[Z:%.*]]
+; CHECK-NEXT:    [[T0_NEG:%.*]] = shl nsw i8 -1, [[Z:%.*]]
 ; CHECK-NEXT:    [[T1_NEG:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0_NEG]]
 ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[T2]]
diff --git a/llvm/test/Transforms/InstCombine/sub-of-negatible.ll b/llvm/test/Transforms/InstCombine/sub-of-negatible.ll
index 1bea723a1ca1286..aacc83eba006150 100644
--- a/llvm/test/Transforms/InstCombine/sub-of-negatible.ll
+++ b/llvm/test/Transforms/InstCombine/sub-of-negatible.ll
@@ -157,7 +157,7 @@ define i8 @t6(i8 %x, i1 %y, i8 %z) {
 }
 define i8 @t7(i8 %x, i1 %y, i8 %z) {
 ; CHECK-LABEL: @t7(
-; CHECK-NEXT:    [[T0_NEG:%.*]] = shl i8 -1, [[Z:%.*]]
+; CHECK-NEXT:    [[T0_NEG:%.*]] = shl nsw i8 -1, [[Z:%.*]]
 ; CHECK-NEXT:    [[T1_NEG:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0_NEG]]
 ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[T2]]
diff --git a/llvm/test/Transforms/InstCombine/sub.ll b/llvm/test/Transforms/InstCombine/sub.ll
index 0bab904850c6d9a..754b532de20083d 100644
--- a/llvm/test/Transforms/InstCombine/sub.ll
+++ b/llvm/test/Transforms/InstCombine/sub.ll
@@ -480,7 +480,7 @@ define i64 @test_neg_shl_div(i64 %a) {
 define i64 @test_neg_shl_zext_i1(i1 %a, i64 %b) {
 ; CHECK-LABEL: @test_neg_shl_zext_i1(
 ; CHECK-NEXT:    [[EXT_NEG:%.*]] = sext i1 [[A:%.*]] to i64
-; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl i64 [[EXT_NEG]], [[B:%.*]]
+; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl nsw i64 [[EXT_NEG]], [[B:%.*]]
 ; CHECK-NEXT:    ret i64 [[SHL_NEG]]
 ;
   %ext = zext i1 %a to i64
@@ -492,7 +492,7 @@ define i64 @test_neg_shl_zext_i1(i1 %a, i64 %b) {
 define i64 @test_neg_shl_sext_i1(i1 %a, i64 %b) {
 ; CHECK-LABEL: @test_neg_shl_sext_i1(
 ; CHECK-NEXT:    [[EXT_NEG:%.*]] = zext i1 [[A:%.*]] to i64
-; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl i64 [[EXT_NEG]], [[B:%.*]]
+; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl nuw i64 [[EXT_NEG]], [[B:%.*]]
 ; CHECK-NEXT:    ret i64 [[SHL_NEG]]
 ;
   %ext = sext i1 %a to i64
@@ -544,7 +544,7 @@ define i32 @test_neg_trunc_shl_sub(i64 %a, i64 %b) {
 define i32 @test_neg_trunc_shl_ashr(i64 %a, i64 %b) {
 ; CHECK-LABEL: @test_neg_trunc_shl_ashr(
 ; CHECK-NEXT:    [[SHR_NEG:%.*]] = lshr i64 [[A:%.*]], 63
-; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl i64 [[SHR_NEG]], [[B:%.*]]
+; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl nuw i64 [[SHR_NEG]], [[B:%.*]]
 ; CHECK-NEXT:    [[TRUNC_NEG:%.*]] = trunc i64 [[SHL_NEG]] to i32
 ; CHECK-NEXT:    ret i32 [[TRUNC_NEG]]
 ;
@@ -558,7 +558,7 @@ define i32 @test_neg_trunc_shl_ashr(i64 %a, i64 %b) {
 define i32 @test_neg_trunc_shl_lshr(i64 %a, i64 %b) {
 ; CHECK-LABEL: @test_neg_trunc_shl_lshr(
 ; CHECK-NEXT:    [[SHR_NEG:%.*]] = ashr i64 [[A:%.*]], 63
-; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl i64 [[SHR_NEG]], [[B:%.*]]
+; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl nsw i64 [[SHR_NEG]], [[B:%.*]]
 ; CHECK-NEXT:    [[TRUNC_NEG:%.*]] = trunc i64 [[SHL_NEG]] to i32
 ; CHECK-NEXT:    ret i32 [[TRUNC_NEG]]
 ;

>From 0913fe19ff93352e4e0dfa93e8b14820f9554b22 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 17 Nov 2023 02:37:01 +0800
Subject: [PATCH 2/2] fixup! [InstCombine] Improve shamt range calculation

---
 .../Transforms/InstCombine/InstCombineShifts.cpp    | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index cf87ae3ace5d1a2..9413e712506bafd 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -968,8 +968,7 @@ static bool setShiftFlags(BinaryOperator &I, const SimplifyQuery &Q) {
   unsigned BitWidth = KnownCnt.getBitWidth();
   // Since shift produces a poison value if RHS is equal to or larger than the
   // bit width, we can safely assume that RHS is less than the bit width.
-  APInt MaxCnt(BitWidth, BitWidth - 1);
-  MaxCnt = APIntOps::umin(MaxCnt, KnownCnt.getUnsignedMax());
+  uint64_t MaxCnt = KnownCnt.getUnsignedMax().getLimitedValue(BitWidth - 1);
 
   KnownBits KnownAmt =
       computeKnownBits(I.getOperand(0), Q.DL, /*Depth*/ 0, Q.AC, Q.CxtI, Q.DT);
@@ -977,15 +976,15 @@ static bool setShiftFlags(BinaryOperator &I, const SimplifyQuery &Q) {
 
   if (I.getOpcode() == Instruction::Shl) {
     // If we have as many leading zeros than maximum shift cnt we have nuw.
-    if (!I.hasNoUnsignedWrap() && MaxCnt.ule(KnownAmt.countMinLeadingZeros())) {
+    if (!I.hasNoUnsignedWrap() && MaxCnt <= KnownAmt.countMinLeadingZeros()) {
       I.setHasNoUnsignedWrap();
       Changed = true;
     }
     // If we have more sign bits than maximum shift cnt we have nsw.
     if (!I.hasNoSignedWrap()) {
-      if (MaxCnt.ult(KnownAmt.countMinSignBits()) ||
-          MaxCnt.ult(ComputeNumSignBits(I.getOperand(0), Q.DL, /*Depth*/ 0,
-                                        Q.AC, Q.CxtI, Q.DT))) {
+      if (MaxCnt < KnownAmt.countMinSignBits() ||
+          MaxCnt < ComputeNumSignBits(I.getOperand(0), Q.DL, /*Depth*/ 0, Q.AC,
+                                      Q.CxtI, Q.DT)) {
         I.setHasNoSignedWrap();
         Changed = true;
       }
@@ -995,7 +994,7 @@ static bool setShiftFlags(BinaryOperator &I, const SimplifyQuery &Q) {
 
   // If we have at least as many trailing zeros as maximum count then we have
   // exact.
-  Changed = MaxCnt.ule(KnownAmt.countMinTrailingZeros());
+  Changed = MaxCnt <= KnownAmt.countMinTrailingZeros();
   I.setIsExact(Changed);
 
   return Changed;



More information about the llvm-commits mailing list