[llvm] 0c553f5 - [InstCombine] Use common flags for shl in shl/trunc fold. (#221769)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 7 11:23:04 PDT 2026


Author: Florian Hahn
Date: 2026-09-07T18:22:58Z
New Revision: 0c553f573a076091f60df21618494584e9641e96

URL: https://github.com/llvm/llvm-project/commit/0c553f573a076091f60df21618494584e9641e96
DIFF: https://github.com/llvm/llvm-project/commit/0c553f573a076091f60df21618494584e9641e96.diff

LOG: [InstCombine] Use common flags for shl in shl/trunc fold. (#221769)

As pointed out post-commit in
https://github.com/llvm/llvm-project/pull/219443, whether the flags from
the trunc can be transferred directly to the shl depends on the involved
types: https://alive2.llvm.org/ce/z/zN_TFq

For now, just use the common flags.

PR: https://github.com/llvm/llvm-project/pull/221769

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index fb56bcc6bea26..54d811fa3e923 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1236,18 +1236,16 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
       APInt Threshold = APInt(C->getType()->getScalarSizeInBits(), DestWidth);
       if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold))) {
         // If neither the wide shift nor the truncate wrap, propagate the wrap
-        // flags on the new truncate.
+        // flags on the new truncate and shift.
         auto *WideShl = cast<OverflowingBinaryOperator>(Src);
         bool NUW = Trunc.hasNoUnsignedWrap() && WideShl->hasNoUnsignedWrap();
         bool NSW = Trunc.hasNoSignedWrap() && WideShl->hasNoSignedWrap();
         Value *NewTrunc = Builder.CreateTrunc(A, DestTy, A->getName() + ".tr",
                                               /*IsNUW=*/NUW, /*IsNSW=*/NSW);
-        // The original flags from the truncate can be propagated directly to
-        // the shift.
         auto *NewShl = BinaryOperator::Create(
             Instruction::Shl, NewTrunc, ConstantExpr::getTrunc(C, DestTy));
-        NewShl->setHasNoUnsignedWrap(Trunc.hasNoUnsignedWrap());
-        NewShl->setHasNoSignedWrap(Trunc.hasNoSignedWrap());
+        NewShl->setHasNoUnsignedWrap(NUW);
+        NewShl->setHasNoSignedWrap(NSW);
         return NewShl;
       }
     }

diff  --git a/llvm/test/Transforms/InstCombine/trunc.ll b/llvm/test/Transforms/InstCombine/trunc.ll
index 59c0f83b0e60c..9e41544043d51 100644
--- a/llvm/test/Transforms/InstCombine/trunc.ll
+++ b/llvm/test/Transforms/InstCombine/trunc.ll
@@ -664,7 +664,7 @@ define i32 @trunc_nuw_shl_nuw_nsw_3_i32_i64(i64 %val) {
 define i32 @trunc_nuw_nsw_shl_nsw_3_i32_i64(i64 %val) {
 ; CHECK-LABEL: @trunc_nuw_nsw_shl_nsw_3_i32_i64(
 ; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc nsw i64 [[VAL:%.*]] to i32
-; CHECK-NEXT:    [[TRUNC:%.*]] = shl nuw nsw i32 [[VAL_TR]], 3
+; CHECK-NEXT:    [[TRUNC:%.*]] = shl nsw i32 [[VAL_TR]], 3
 ; CHECK-NEXT:    ret i32 [[TRUNC]]
 ;
   %shl = shl nsw i64 %val, 3
@@ -676,7 +676,7 @@ define i32 @trunc_nuw_nsw_shl_nsw_3_i32_i64(i64 %val) {
 define i32 @trunc_nuw_shl_3_i32_i64(i64 %val) {
 ; CHECK-LABEL: @trunc_nuw_shl_3_i32_i64(
 ; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i32
-; CHECK-NEXT:    [[TRUNC:%.*]] = shl nuw i32 [[VAL_TR]], 3
+; CHECK-NEXT:    [[TRUNC:%.*]] = shl i32 [[VAL_TR]], 3
 ; CHECK-NEXT:    ret i32 [[TRUNC]]
 ;
   %shl = shl i64 %val, 3
@@ -700,7 +700,7 @@ define i32 @trunc_shl_nuw_nsw_3_i32_i64(i64 %val) {
 define i32 @trunc_nuw_shl_nsw_3_i32_i64(i64 %val) {
 ; CHECK-LABEL: @trunc_nuw_shl_nsw_3_i32_i64(
 ; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i32
-; CHECK-NEXT:    [[TRUNC:%.*]] = shl nuw i32 [[VAL_TR]], 3
+; CHECK-NEXT:    [[TRUNC:%.*]] = shl i32 [[VAL_TR]], 3
 ; CHECK-NEXT:    ret i32 [[TRUNC]]
 ;
   %shl = shl nsw i64 %val, 3
@@ -708,6 +708,17 @@ define i32 @trunc_nuw_shl_nsw_3_i32_i64(i64 %val) {
   ret i32 %trunc
 }
 
+define i4 @trunc_nuw_shl_i6_to_i4(i6 %x, i6 %y) {
+; CHECK-LABEL: @trunc_nuw_shl_i6_to_i4(
+; CHECK-NEXT:    [[X_TR:%.*]] = trunc i6 [[X:%.*]] to i4
+; CHECK-NEXT:    [[TRUNC:%.*]] = shl i4 [[X_TR]], 3
+; CHECK-NEXT:    ret i4 [[TRUNC]]
+;
+  %shl = shl i6 %x, 3
+  %trunc = trunc nuw i6 %shl to i4
+  ret i4 %trunc
+}
+
 define i16 @trunc_shl_15_i16_i64(i64 %val) {
 ; CHECK-LABEL: @trunc_shl_15_i16_i64(
 ; CHECK-NEXT:    [[VAL_TR:%.*]] = trunc i64 [[VAL:%.*]] to i16


        


More information about the llvm-commits mailing list