Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -7307,8 +7307,8 @@ // trunc (select c, a, b) -> select c, (trunc a), (trunc b) if (N0.getOpcode() == ISD::SELECT) { EVT SrcVT = N0.getValueType(); - if ((!LegalOperations || TLI.isOperationLegal(ISD::SELECT, SrcVT)) && - TLI.isTruncateFree(SrcVT, VT)) { + if ((!LegalOperations || TLI.isOperationLegal(ISD::SELECT, SrcVT)) && + N0.hasOneUse() && TLI.isTruncateFree(SrcVT, VT)) { SDLoc SL(N0); SDValue Cond = N0.getOperand(0); SDValue TruncOp0 = DAG.getNode(ISD::TRUNCATE, SL, VT, N0.getOperand(1)); Index: test/CodeGen/X86/select.ll =================================================================== --- test/CodeGen/X86/select.ll +++ test/CodeGen/X86/select.ll @@ -515,6 +515,33 @@ ret i32 %tmp2 } + +define i16 @trunc_select_negative(i8 %a, i16 %b) { +entry: +; CHECK-LABEL: trunc_select: +; CHECK: ## BB#0: +; CHECK: cmovew +; CHECK: cmovew +; CHECK-NOT: cmovew +; CHECK: retq + %b.tr = trunc i16 %b to i8 + %and.0 = xor i8 %b.tr, %a + %xor.0 = and i8 %and.0, 1 + %shr.0 = lshr i8 %a, 1 + %cond = icmp eq i8 %xor.0, 0 + %shr.1 = lshr i16 %b, 1 + %0 = xor i16 %shr.1, -432 + %1 = select i1 %cond, i16 %shr.1, i16 %0 + %b.tr.1 = trunc i16 %1 to i8 + %and.1 = xor i8 %b.tr.1, %shr.0 + %xor.1 = and i8 %and.1, 1 + %cond.1 = icmp eq i8 %xor.1, 0 + %shr.2 = lshr i16 %1, 1 + %2 = xor i16 %shr.2, -231 + %3 = select i1 %cond.1, i16 %shr.2, i16 %2 + ret i16 %3 +} + define void @test19() { ; This is a massive reduction of an llvm-stress test case that generates ; interesting chains feeding setcc and eventually a f32 select operation. This