Index: llvm/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/lib/Analysis/InstructionSimplify.cpp +++ llvm/lib/Analysis/InstructionSimplify.cpp @@ -4253,13 +4253,10 @@ return RepOp; // We cannot replace a constant, and shouldn't even try. - if (isa(Op)) - return nullptr; - - auto *I = dyn_cast(V); - if (!I || !is_contained(I->operands(), Op)) + if (isa(Op) || !isa(V)) return nullptr; + auto *I = cast(V); // The arguments of a phi node might refer to a value from a previous // cycle iteration. if (isa(I)) @@ -4278,6 +4275,25 @@ transform(I->operands(), NewOps.begin(), [&](Value *V) { return V == Op ? RepOp : V; }); + // TODO: support more type operator + if (dyn_cast(I) && !is_contained(I->operands(), Op)) { + for (unsigned Idx = 0, E = I->getNumOperands(); Idx < E; ++Idx) { + Value *NewV = I->getOperand(Idx); + if (!isa(NewV)) + continue; + auto *NewI = cast(NewV); + if (NewI->getParent() != I->getParent()) + continue; + Value *S = simplifyWithOpReplaced(NewV, Op, RepOp, Q, AllowRefinement, + MaxRecurse - 1); + if (!S) + continue; + Constant *Cst = dyn_cast(S); + if (Cst && Cst->isNullValue()) + NewOps[Idx] = Cst; + } + } + if (!AllowRefinement) { // General InstSimplify functions may refine the result, e.g. by returning // a constant for a potentially poison value. To avoid this, implement only Index: llvm/test/Transforms/InstCombine/select-cmp.ll =================================================================== --- llvm/test/Transforms/InstCombine/select-cmp.ll +++ llvm/test/Transforms/InstCombine/select-cmp.ll @@ -345,4 +345,18 @@ ret i1 %r } +; https://alive2.llvm.org/ce/z/TGgJTq +define i32 @select_icmp_xor_multi_insn(i32 noundef %a, i32 noundef %b) { +; CHECK-LABEL: @select_icmp_xor_multi_insn( +; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[TMP1]], -1 +; CHECK-NEXT: ret i32 [[XOR1]] +; + %tobool = icmp eq i32 %a, %b + %not = xor i32 %a, -1 + %xor1 = xor i32 %not, %b + %cond = select i1 %tobool, i32 -1, i32 %xor1 + ret i32 %cond +} + declare void @use(i1)