[llvm] 89a8a0c - [InstCombine] Inherit exact flags on extended shifts in trunc (lshr (sext A), C) --> (ashr A, C)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 07:32:23 PDT 2020


Author: Simon Pilgrim
Date: 2020-09-29T15:32:09+01:00
New Revision: 89a8a0c910422b9d363120769e2eebda03394b0f

URL: https://github.com/llvm/llvm-project/commit/89a8a0c910422b9d363120769e2eebda03394b0f
DIFF: https://github.com/llvm/llvm-project/commit/89a8a0c910422b9d363120769e2eebda03394b0f.diff

LOG: [InstCombine] Inherit exact flags on extended shifts in trunc (lshr (sext A), C) --> (ashr A, C)

This was missed in D88475

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
    llvm/test/Transforms/InstCombine/cast.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index ca55c8f5a887..fb885790d448 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -831,6 +831,8 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
   if (match(Src, m_LShr(m_SExt(m_Value(A)), m_Constant(C)))) {
     unsigned AWidth = A->getType()->getScalarSizeInBits();
     unsigned MaxShiftAmt = SrcWidth - std::max(DestWidth, AWidth);
+    auto *OldSh = cast<Instruction>(Src);
+    bool IsExact = OldSh->isExact();
 
     // If the shift is small enough, all zero bits created by the shift are
     // removed by the trunc.
@@ -843,7 +845,8 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
         Constant *MaxAmt = ConstantInt::get(SrcTy, DestWidth - 1, false);
         Constant *ShAmt = ConstantExpr::getUMin(C, MaxAmt);
         ShAmt = ConstantExpr::getTrunc(ShAmt, A->getType());
-        return BinaryOperator::CreateAShr(A, ShAmt);
+        return IsExact ? BinaryOperator::CreateExactAShr(A, ShAmt)
+                       : BinaryOperator::CreateAShr(A, ShAmt);
       }
       // The types are mismatched, so create a cast after shifting:
       // trunc (lshr (sext A), C) --> sext/trunc (ashr A, C)
@@ -851,7 +854,7 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
         Constant *MaxAmt = ConstantInt::get(SrcTy, AWidth - 1, false);
         Constant *ShAmt = ConstantExpr::getUMin(C, MaxAmt);
         ShAmt = ConstantExpr::getTrunc(ShAmt, A->getType());
-        Value *Shift = Builder.CreateAShr(A, ShAmt);
+        Value *Shift = Builder.CreateAShr(A, ShAmt, "", IsExact);
         return CastInst::CreateIntegerCast(Shift, DestTy, true);
       }
     }

diff  --git a/llvm/test/Transforms/InstCombine/cast.ll b/llvm/test/Transforms/InstCombine/cast.ll
index db6b550f5faa..97439606973c 100644
--- a/llvm/test/Transforms/InstCombine/cast.ll
+++ b/llvm/test/Transforms/InstCombine/cast.ll
@@ -1548,7 +1548,7 @@ define i8 @trunc_lshr_sext(i8 %A) {
 
 define i8 @trunc_lshr_sext_exact(i8 %A) {
 ; ALL-LABEL: @trunc_lshr_sext_exact(
-; ALL-NEXT:    [[D:%.*]] = ashr i8 [[A:%.*]], 6
+; ALL-NEXT:    [[D:%.*]] = ashr exact i8 [[A:%.*]], 6
 ; ALL-NEXT:    ret i8 [[D]]
 ;
   %B = sext i8 %A to i32
@@ -1718,7 +1718,7 @@ define i8 @trunc_lshr_sext_wide_input(i16 %A) {
 
 define i8 @trunc_lshr_sext_wide_input_exact(i16 %A) {
 ; ALL-LABEL: @trunc_lshr_sext_wide_input_exact(
-; ALL-NEXT:    [[TMP1:%.*]] = ashr i16 [[A:%.*]], 9
+; ALL-NEXT:    [[TMP1:%.*]] = ashr exact i16 [[A:%.*]], 9
 ; ALL-NEXT:    [[D:%.*]] = trunc i16 [[TMP1]] to i8
 ; ALL-NEXT:    ret i8 [[D]]
 ;


        


More information about the llvm-commits mailing list