diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 2229743b923..e24a2942dd9 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2119,6 +2119,9 @@ SDOperand DAGCombiner::visitXOR(SDNode *N) { if (FoldedVOp.Val) return FoldedVOp; } + // fold (xor undef, undef) -> 0. This is a common idiom (misuse). + if (N0.getOpcode() == ISD::UNDEF && N1.getOpcode() == ISD::UNDEF) + return DAG.getConstant(0, VT); // fold (xor x, undef) -> undef if (N0.getOpcode() == ISD::UNDEF) return N0; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 05f7edb47cc..ed564b2b7b8 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2245,6 +2245,12 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, // Fold a bunch of operators when the RHS is undef. if (N2.getOpcode() == ISD::UNDEF) { switch (Opcode) { + case ISD::XOR: + if (N1.getOpcode() == ISD::UNDEF) + // Handle undef ^ undef -> 0 special case. This is a common + // idiom (misuse). + return getConstant(0, VT); + // fallthrough case ISD::ADD: case ISD::ADDC: case ISD::ADDE: @@ -2258,7 +2264,6 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, case ISD::SDIV: case ISD::UREM: case ISD::SREM: - case ISD::XOR: return N2; // fold op(arg1, undef) -> undef case ISD::MUL: case ISD::AND: diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 762a24a2633..7b21817cda4 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -474,9 +474,14 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, // Handle UndefValue up front if (isa(C1) || isa(C2)) { switch (Opcode) { + case Instruction::Xor: + if (isa(C1) && isa(C2)) + // Handle undef ^ undef -> 0 special case. This is a common + // idiom (misuse). + return Constant::getNullValue(C1->getType()); + // Fallthrough case Instruction::Add: case Instruction::Sub: - case Instruction::Xor: return UndefValue::get(C1->getType()); case Instruction::Mul: case Instruction::And: diff --git a/test/CodeGen/X86/xor-undef.ll b/test/CodeGen/X86/xor-undef.ll new file mode 100644 index 00000000000..0e60d4ef087 --- /dev/null +++ b/test/CodeGen/X86/xor-undef.ll @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep xor | count 2 + +define <4 x i32> @t1() { + %tmp = xor <4 x i32> undef, undef + ret <4 x i32> %tmp +} + +define i32 @t2() { + %tmp = xor i32 undef, undef + ret i32 %tmp +}