[llvm] [InstCombine] Match swapped form of truncating saturation clamp (PR #226614)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 27 06:47:47 PDT 2026
================
@@ -1253,18 +1253,25 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
// trunc (select(icmp_ult(A, DestTy_umax+1), A, sext(icmp_sgt(A, 0)))) -->
// trunc (smin(smax(0, A), DestTy_umax))
- if (SrcTy->isIntegerTy() && isPowerOf2_64(SrcTy->getPrimitiveSizeInBits()) &&
- isPowerOf2_64(DestTy->getPrimitiveSizeInBits()) &&
- match(Src, m_OneUse(m_Select(
- m_OneUse(m_SpecificICmp(ICmpInst::ICMP_ULT, m_Value(A),
- m_Constant(C))),
- m_Deferred(A),
- m_OneUse(m_SExt(m_OneUse(m_SpecificICmp(
- ICmpInst::ICMP_SGT, m_Deferred(A), m_Zero())))))))) {
- APInt UpperBound = C->getUniqueInteger();
- APInt TruncatedMax = APInt::getAllOnes(DestTy->getIntegerBitWidth());
- TruncatedMax = TruncatedMax.zext(UpperBound.getBitWidth());
- if (!UpperBound.isZero() && UpperBound - 1 == TruncatedMax) {
+ // Also handle the inverted form:
+ // trunc (select(icmp_ugt(A, DestTy_umax), sext(icmp_sgt(A, 0)), A))
+ CmpPredicate Pred;
+ const APInt *CmpC;
+ Value *TVal, *FVal;
+ if (SrcTy->isIntegerTy() && isPowerOf2_64(SrcWidth) &&
+ isPowerOf2_64(DestWidth) &&
+ match(Src,
+ m_OneUse(m_Select(m_OneUse(m_ICmp(Pred, m_Value(A), m_APInt(CmpC))),
+ m_Value(TVal), m_Value(FVal))))) {
+ APInt TruncatedMax = APInt::getLowBitsSet(SrcWidth, DestWidth);
+ Value *SExtVal = nullptr;
+ if (Pred == ICmpInst::ICMP_ULT && *CmpC == TruncatedMax + 1 && TVal == A)
----------------
dtcxzyw wrote:
Check `T/FVal == A` first.
Reproducer:
```
; bin/opt -passes=instcombine reduced.ll -S
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
define fastcc i32 @dotCmdMode(i32 %0, i64 %.1.i, i64 %1) {
.thread935:
%2 = icmp ult i32 %0, 2
%.2.i = select i1 %2, i64 %1, i64 %.1.i
%3 = trunc i64 %.2.i to i32
ret i32 %3
}
```
```
opt: /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/APInt.h:1061: bool llvm::APInt::operator==(const llvm::APInt&) const: Assertion `BitWidth == RHS.BitWidth && "Comparison requires equal bit widths"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and instructions to reproduce the bug.
Stack dump:
0. Program arguments: bin/opt -passes=instcombine reduced.ll -S
1. Running pass "function(instcombine<max-iterations=1;verify-fixpoint>)" on module "reduced.ll"
2. Running pass "instcombine<max-iterations=1;verify-fixpoint>" on function "dotCmdMode"
#0 0x00007ffff7dfddd1 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /data/zyw/dev/llvm-project/llvm/lib/Support/Unix/Signals.inc:935:3
#1 0x00007ffff7dfabdc llvm::sys::RunSignalHandlers() /data/zyw/dev/llvm-project/llvm/lib/Support/Signals.cpp:108:20
#2 0x00007ffff7dfb455 SignalHandler(int, siginfo_t*, void*) /data/zyw/dev/llvm-project/llvm/lib/Support/Unix/Signals.inc:474:14
#3 0x00007ffff7845330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
#4 0x00007ffff789ec0c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
#5 0x00007ffff789ec0c __pthread_kill_internal ./nptl/pthread_kill.c:78:10
#6 0x00007ffff789ec0c pthread_kill ./nptl/pthread_kill.c:89:10
#7 0x00007ffff784527e raise ./signal/../sysdeps/posix/raise.c:27:6
#8 0x00007ffff78288ff abort ./stdlib/abort.c:81:7
#9 0x00007ffff782881b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x00007ffff783b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517)
#11 0x00007fffeec5ce45 (/data/zyw/dev/llvm-build/bin/../lib/../lib/libLLVMInstCombine.so.24.0git+0x5ce45)
#12 0x00007fffeec5e6db (/data/zyw/dev/llvm-build/bin/../lib/../lib/libLLVMInstCombine.so.24.0git+0x5e6db)
#13 0x00007fffeece32fd llvm::InstCombinerImpl::visitTrunc(llvm::TruncInst&) /data/zyw/dev/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp:1268:36
#14 0x00007fffeec5922b llvm::InstCombinerImpl::run() /data/zyw/dev/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp:5910:36
#15 0x00007fffeec5b0cb combineInstructionsOverFunction(llvm::Function&, llvm::InstructionWorklist&, llvm::AAResults*, llvm::AssumptionCache&, llvm::TargetLibraryInfo&, llvm::TargetTransformInfo&, llvm::DominatorTree&, llvm::OptimizationRemarkEmitter&, llvm::BlockFrequencyInfo*, llvm::BranchProbabilityInfo*, llvm::ProfileSummaryInfo*, llvm::InstCombineOptions const&) /data/zyw/dev/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp:6218:5
#16 0x00007fffeec5be6a llvm::InstCombinePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /data/zyw/dev/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp:6279:3
#17 0x00007ffff1080845 llvm::detail::PassModel<llvm::Function, llvm::InstCombinePass, llvm::AnalysisManager<llvm::Function>>::runImpl(llvm::detail::PassConcept<llvm::Function, llvm::AnalysisManager<llvm::Function>>&, llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:129:3
#18 0x00007fffedcf8bb1 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h:80:18
#19 0x00007ffff10614d5 llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::runImpl(llvm::detail::PassConcept<llvm::Function, llvm::AnalysisManager<llvm::Function>>&, llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:129:3
#20 0x00007fffedcf785b llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /data/zyw/dev/llvm-project/llvm/lib/IR/PassManager.cpp:153:41
#21 0x00007ffff10615d5 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::runImpl(llvm::detail::PassConcept<llvm::Module, llvm::AnalysisManager<llvm::Module>>&, llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:129:3
#22 0x00007fffedcf7172 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /data/zyw/dev/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h:80:18
#23 0x00007ffff7f9a524 llvm::SmallPtrSetImplBase::~SmallPtrSetImplBase() /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h:91:5
#24 0x00007ffff7f9a524 llvm::SmallPtrSetImpl<llvm::AnalysisKey*>::~SmallPtrSetImpl() /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h:352:35
#25 0x00007ffff7f9a524 llvm::SmallPtrSet<llvm::AnalysisKey*, 2u>::~SmallPtrSet() /data/zyw/dev/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h:519:7
#26 0x00007ffff7f9a524 llvm::PreservedAnalyses::~PreservedAnalyses() /data/zyw/dev/llvm-project/llvm/include/llvm/IR/Analysis.h:112:7
#27 0x00007ffff7f9a524 llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::ArrayRef<std::function<void (llvm::PassBuilder&)>>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool, bool) /data/zyw/dev/llvm-project/llvm/tools/opt/NewPMDriver.cpp:608:10
#28 0x00007ffff7fa6083 optMain /data/zyw/dev/llvm-project/llvm/tools/opt/optdriver.cpp:801:5
#29 0x0000555555555116 main /data/zyw/dev/llvm-project/llvm/tools/opt/opt.cpp:31:1
#30 0x00007ffff782a1ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#31 0x00007ffff782a28b call_init ./csu/../csu/libc-start.c:128:20
#32 0x00007ffff782a28b __libc_start_main ./csu/../csu/libc-start.c:347:5
#33 0x0000555555555175 _start (bin/opt+0x1175)
Aborted (core dumped)
```
https://github.com/llvm/llvm-project/pull/226614
More information about the llvm-commits
mailing list