[llvm] [InstCombine] Fold `(x < y) ? -1 : zext(x != y)` into `u/scmp(x,y)` (PR #101049)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 29 12:07:26 PDT 2024


================
@@ -3529,6 +3529,38 @@ static Instruction *foldBitCeil(SelectInst &SI, IRBuilderBase &Builder) {
                                 Masked);
 }
 
+// This function tries to fold the following sequence
+//   %lt = icmp ult/slt i32 %x, %y
+//   %ne0 = icmp ne i32 %x, %y
+//   %ne = zext i1 %ne0 to iN
+//   %r = select i1 %lt, iN -1, iN %ne
+// into
+//   %r = call iN @llvm.ucmp/scmp(%x, %y)
+Instruction *InstCombinerImpl::foldSelectToCmp(SelectInst &SI) {
+  if (!isa<Constant>(SI.getTrueValue()) ||
+      !dyn_cast<Constant>(SI.getTrueValue())->isAllOnesValue())
+    return nullptr;
+
+  Value *LHS, *RHS;
+  ICmpInst::Predicate NEPred;
+  if (!match(SI.getFalseValue(),
+             m_ZExt(m_ICmp(NEPred, m_Value(LHS), m_Value(RHS)))) ||
+      NEPred != ICmpInst::ICMP_NE)
+    return nullptr;
+
+  ICmpInst::Predicate LTPred;
+  if (!match(SI.getCondition(),
+             m_ICmp(LTPred, m_Specific(LHS), m_Specific(RHS))) ||
+      !ICmpInst::isLT(LTPred))
+    return nullptr;
+
+  bool IsSigned = ICmpInst::isSigned(LTPred);
+  Instruction *Result = Builder.CreateIntrinsic(
----------------
dtcxzyw wrote:

```
; 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-pc-linux-gnu"

define i32 @_ZNK6Symbol12fast_compareEPKS_(ptr %0, ptr %1) {
  %3 = icmp ult ptr %0, %1
  %4 = icmp ne ptr %0, %1
  %5 = zext i1 %4 to i32
  %6 = select i1 %3, i32 -1, i32 %5
  ret i32 %6
}
```
```
opt: /home/dtcxzyw/WorkSpace/Projects/compilers/llvm-project/llvm/lib/IR/IRBuilder.cpp:962: llvm::CallInst* llvm::IRBuilderBase::CreateIntrinsic(llvm::Type*, llvm::Intrinsic::ID, llvm::ArrayRef<llvm::Value*>, llvm::Instruction*, const llvm::Twine&): Assertion `Res == Intrinsic::MatchIntrinsicTypes_Match && TableRef.empty() && "Wrong types for intrinsic!"' 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 reduced.ll
1.      Running pass "function(instcombine<max-iterations=1;no-use-loop-info;verify-fixpoint>)" on module "reduced.ll"
2.      Running pass "instcombine<max-iterations=1;no-use-loop-info;verify-fixpoint>" on function "_ZNK6Symbol12fast_compareEPKS_"
 #0 0x00007ffff7e0f7f2 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMSupport.so.20.0git+0x20f7f2)
 #1 0x00007ffff7e0c6bf llvm::sys::RunSignalHandlers() (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMSupport.so.20.0git+0x20c6bf)
 #2 0x00007ffff7e0c805 SignalHandler(int) Signals.cpp:0:0
 #3 0x00007ffff7842520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x00007ffff78969fc __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x00007ffff78969fc __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x00007ffff78969fc pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x00007ffff7842476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x00007ffff78287f3 abort ./stdlib/abort.c:81:7
 #9 0x00007ffff782871b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x00007ffff7839e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#11 0x00007ffff0295e59 llvm::IRBuilderBase::CreateIntrinsic(llvm::Type*, unsigned int, llvm::ArrayRef<llvm::Value*>, llvm::Instruction*, llvm::Twine const&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMCore.so.20.0git+0x295e59)
#12 0x00007ffff476af95 llvm::InstCombinerImpl::foldSelectToCmp(llvm::SelectInst&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMInstCombine.so.20.0git+0x14ff95)
#13 0x00007ffff4776a12 llvm::InstCombinerImpl::visitSelectInst(llvm::SelectInst&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMInstCombine.so.20.0git+0x15ba12)
#14 0x00007ffff467b9bd llvm::InstCombinerImpl::run() (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMInstCombine.so.20.0git+0x609bd)
#15 0x00007ffff467c99c combineInstructionsOverFunction(llvm::Function&, llvm::InstructionWorklist&, llvm::AAResults*, llvm::AssumptionCache&, llvm::TargetLibraryInfo&, llvm::TargetTransformInfo&, llvm::DominatorTree&, llvm::OptimizationRemarkEmitter&, llvm::BlockFrequencyInfo*, llvm::BranchProbabilityInfo*, llvm::ProfileSummaryInfo*, llvm::LoopInfo*, llvm::InstCombineOptions const&) InstructionCombining.cpp:0:0
#16 0x00007ffff467da22 llvm::InstCombinePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMInstCombine.so.20.0git+0x62a22)
#17 0x00007ffff32ce835 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/libLLVMPasses.so.20.0git+0xce835)
#18 0x00007ffff0351b25 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.20.0git+0x351b25)
#19 0x00007ffff68d5c25 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.20.0git+0xd5c25)
#20 0x00007ffff0350676 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMCore.so.20.0git+0x350676)
#21 0x00007ffff68d6545 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.20.0git+0xd6545)
#22 0x00007ffff034e68a 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.20.0git+0x34e68a)
#23 0x00007ffff7f94277 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.20.0git+0x2d277)
#24 0x00007ffff7fa0296 optMain (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMOptDriver.so.20.0git+0x39296)
#25 0x00007ffff7829d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#26 0x00007ffff7829e40 call_init ./csu/../csu/libc-start.c:128:20
#27 0x00007ffff7829e40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#28 0x0000555555555095 _start (bin/opt+0x1095)
Aborted (core dumped)
```

@nikic Do we plan to support `llvm.ucmp.i32.ptr`?

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


More information about the llvm-commits mailing list