Index: lib/Transforms/Scalar/EarlyCSE.cpp =================================================================== --- lib/Transforms/Scalar/EarlyCSE.cpp +++ lib/Transforms/Scalar/EarlyCSE.cpp @@ -578,6 +578,28 @@ continue; } + if (CmpInst *CI = dyn_cast(Inst)) { + Value *X, *Y; + ConstantInt *C; + bool IdempotentUser = false; + for (auto *U : CI->users()) { + if (match(U, m_Select(m_Value(X), m_ConstantInt(C), m_Value(Y))) || + match(U, m_Select(m_Value(X), m_Value(Y), m_ConstantInt(C)))) { + if (C->isOne() || C->isZero()) { + if (!AvailableValues.lookup(Inst)) + AvailableValues.insert(Inst, Inst); + IdempotentUser = true; + break; + } + } + } + if (IdempotentUser) { + DEBUG(dbgs() << "EarlyCSE skipping compare inst: " << *Inst + << " in " << BB->getName() << "\n"); + continue; + } + } + // If this is a simple instruction that we can value number, process it. if (SimpleValue::canHandle(Inst)) { // See if the instruction has an available value. If so, use it. Index: test/Transforms/EarlyCSE/basic.ll =================================================================== --- test/Transforms/EarlyCSE/basic.ll +++ test/Transforms/EarlyCSE/basic.ll @@ -277,3 +277,23 @@ ret void } +define void @cond_idem(i32 %A, i32 %B, i32 %C) #0 { +; CHECK-LABEL: @cond_idem( +entry: + %cmp = icmp sgt i32 %A, 0 +; CHECK: %cmp = icmp sgt i32 %A, 0 + %cmp1 = icmp sgt i32 %B, 0 + %cmp1. = select i1 %cmp, i1 %cmp1, i1 false + %lnot = xor i1 %cmp1., true + %conv = zext i1 %lnot to i32 + %cmp2 = icmp sgt i32 %A, 0 +; CHECK: %cmp2 = icmp sgt i32 %A, 0 + %cmp4 = icmp sgt i32 %C, 0 + %0 = select i1 %cmp2, i1 %cmp4, i1 false + %lnot6 = xor i1 %0, true + %conv7 = zext i1 %lnot6 to i32 + call void @foo(i32 %conv, i32 %conv7) + ret void +} + +declare void @foo(i32, i32) #0