[llvm] [InstCombine] Combine or-disjoint (and->mul), (and->mul) to and->mul (PR #136013)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sat May 24 01:24:09 PDT 2025


================
@@ -3560,6 +3560,77 @@ static Value *foldOrOfInversions(BinaryOperator &I,
   return nullptr;
 }
 
+// A decomposition of ((A & N) ? 0 : N * C) . Where X = A, Factor = C, Mask = N.
+// The NUW / NSW bools
+// Note that we can decompose equivalent forms of this expression (e.g. ((A & N)
+// * C))
+struct DecomposedBitMaskMul {
+  Value *X;
+  APInt Factor;
+  APInt Mask;
+  bool NUW;
+  bool NSW;
+};
+
+static std::optional<DecomposedBitMaskMul> matchBitmaskMul(Value *V) {
+  Instruction *Op = dyn_cast<Instruction>(V);
+  if (!Op)
+    return std::nullopt;
+
+  Value *MulOp = nullptr;
+  const APInt *MulConst = nullptr;
+
+  // Decompose (A & N) * C) into BitMaskMul
+  if (match(Op, m_Mul(m_Value(MulOp), m_APInt(MulConst)))) {
+    Value *Original = nullptr;
+    const APInt *Mask = nullptr;
+    if (MulConst->isZero())
+      return std::nullopt;
+
+    if (match(MulOp, m_And(m_Value(Original), m_APInt(Mask)))) {
+      if (Mask->isZero())
+        return std::nullopt;
+      return std::optional<DecomposedBitMaskMul>(
+          {Original, *MulConst, *Mask,
+           cast<BinaryOperator>(Op)->hasNoUnsignedWrap(),
+           cast<BinaryOperator>(Op)->hasNoSignedWrap()});
+    }
+    return std::nullopt;
+  }
+
+  Value *Cond = nullptr;
+  const APInt *EqZero = nullptr, *NeZero = nullptr;
+
+  // Decompose ((A & N) ? 0 : N * C) into BitMaskMul
+  if (match(Op, m_Select(m_Value(Cond), m_APInt(EqZero), m_APInt(NeZero)))) {
+    auto ICmpDecompose =
+        decomposeBitTest(Cond, /*LookThruTrunc=*/true,
+                         /*AllowNonZeroC=*/false, /*DecomposeBitMask=*/true);
+    if (!ICmpDecompose.has_value())
+      return std::nullopt;
+
+    if (ICmpDecompose->Pred == ICmpInst::ICMP_NE)
+      std::swap(EqZero, NeZero);
+
+    if (!EqZero->isZero() || NeZero->isZero())
+      return std::nullopt;
+
+    if (!ICmpInst::isEquality(ICmpDecompose->Pred) ||
+        !ICmpDecompose->C.isZero() || !ICmpDecompose->Mask.isPowerOf2() ||
+        ICmpDecompose->Mask.isZero())
+      return std::nullopt;
+
+    if (!NeZero->urem(ICmpDecompose->Mask).isZero())
----------------
dtcxzyw wrote:

Crash reproducer:
```
; bin/opt -passes=instcombine test.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-unknown-linux-gnu"

define i32 @usb_submit_urb(i8 %0, i32 %1) {
  %3 = icmp sgt i8 %0, -1
  %4 = select i1 %3, i32 0, i32 512
  %5 = or disjoint i32 %1, %4
  ret i32 %5
}
```
```
opt: /home/dtcxzyw/WorkSpace/Projects/compilers/llvm-project/llvm/lib/Support/APInt.cpp:1667: llvm::APInt llvm::APInt::urem(const llvm::APInt&) const: Assertion `BitWidth == RHS.BitWidth && "Bit widths must be the same"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: bin/opt -passes=instcombine test.ll -S
1.      Running pass "function(instcombine<max-iterations=1;verify-fixpoint>)" on module "test.ll"
2.      Running pass "instcombine<max-iterations=1;verify-fixpoint>" on function "usb_submit_urb"
 #0 0x00007ab1f5827ec2 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMSupport.so.21.0git+0x227ec2)
 #1 0x00007ab1f5824d9f llvm::sys::RunSignalHandlers() (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMSupport.so.21.0git+0x224d9f)
 #2 0x00007ab1f5824ee4 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #3 0x00007ab1f5245330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
 #4 0x00007ab1f529eb2c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x00007ab1f529eb2c __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x00007ab1f529eb2c pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x00007ab1f524527e raise ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x00007ab1f52288ff abort ./stdlib/abort.c:81:7
 #9 0x00007ab1f522881b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x00007ab1f523b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517)
#11 0x00007ab1f56b7745 llvm::APInt::urem(llvm::APInt const&) const (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMSupport.so.21.0git+0xb7745)
#12 0x00007ab1ed49f336 matchBitmaskMul(llvm::Value*) InstCombineAndOrXor.cpp:0:0
#13 0x00007ab1ed4b180e llvm::InstCombinerImpl::visitOr(llvm::BinaryOperator&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMInstCombine.so.21.0git+0xaa80e)
#14 0x00007ab1ed46ed58 llvm::InstCombinerImpl::run() (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMInstCombine.so.21.0git+0x67d58)
#15 0x00007ab1ed46fe63 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&) InstructionCombining.cpp:0:0
#16 0x00007ab1ed470e72 llvm::InstCombinePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMInstCombine.so.21.0git+0x69e72)
#17 0x00007ab1ef9ac525 llvm::detail::PassModel<llvm::Function, llvm::InstCombinePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libPolly.so.21.0git+0x1ac525)
#18 0x00007ab1ec327694 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMCore.so.21.0git+0x327694)
#19 0x00007ab1f42db8f5 llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMX86CodeGen.so.21.0git+0xdb8f5)
#20 0x00007ab1ec327bb0 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMCore.so.21.0git+0x327bb0)
#21 0x00007ab1f42dc2b5 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMX86CodeGen.so.21.0git+0xdc2b5)
#22 0x00007ab1ec328d35 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMCore.so.21.0git+0x328d35)
#23 0x00007ab1f59cc2e9 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) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMOptDriver.so.21.0git+0x2c2e9)
#24 0x00007ab1f59d7306 optMain (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMOptDriver.so.21.0git+0x37306)
#25 0x00007ab1f522a1ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#26 0x00007ab1f522a28b call_init ./csu/../csu/libc-start.c:128:20
#27 0x00007ab1f522a28b __libc_start_main ./csu/../csu/libc-start.c:347:5
#28 0x00005ec671a92095 _start (bin/opt+0x1095)

Aborted (core dumped)
```

https://github.com/llvm/llvm-project/pull/136013


More information about the llvm-commits mailing list