forked from OSchip/llvm-project
Implement a couple of more simplifications. This lets us codegen:
int test2(int * P, int* Q, int A, int B) { return P+A == P; } into: test2: movl 4(%esp), %eax movl 12(%esp), %eax shll $2, %eax cmpl $0, %eax sete %al movzbl %al, %eax ret instead of: test2: movl 4(%esp), %eax movl 12(%esp), %ecx leal (%eax,%ecx,4), %ecx cmpl %eax, %ecx sete %al movzbl %al, %eax ret ICC is producing worse code: test2: movl 4(%esp), %eax #8.5 movl 12(%esp), %edx #8.5 lea (%edx,%edx), %ecx #9.9 addl %ecx, %ecx #9.9 addl %eax, %ecx #9.9 cmpl %eax, %ecx #9.16 movl $0, %eax #9.16 sete %al #9.16 ret #9.16 as is GCC (looks like our old code): test2: movl 4(%esp), %edx movl 12(%esp), %eax leal (%edx,%eax,4), %ecx cmpl %edx, %ecx sete %al movzbl %al, %eax ret llvm-svn: 19430
This commit is contained in:
parent
00c231baa7
commit
41b764144d
|
@ -398,10 +398,12 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, SDOperand N1,
|
|||
Cond = UOF == 0 ? ISD::SETUO : ISD::SETO;
|
||||
}
|
||||
|
||||
// Simplify (X+Y) == (X+Z) --> Y == Z
|
||||
if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
|
||||
N1.getOpcode() == N2.getOpcode() && MVT::isInteger(N1.getValueType()))
|
||||
if (N1.getOpcode() == ISD::ADD || N1.getOpcode() == ISD::SUB) {
|
||||
MVT::isInteger(N1.getValueType())) {
|
||||
if (N1.getOpcode() == ISD::ADD || N1.getOpcode() == ISD::SUB ||
|
||||
N1.getOpcode() == ISD::XOR) {
|
||||
// Simplify (X+Y) == (X+Z) --> Y == Z
|
||||
if (N1.getOpcode() == N2.getOpcode()) {
|
||||
if (N1.getOperand(0) == N2.getOperand(0))
|
||||
return getSetCC(Cond, N1.getOperand(1), N2.getOperand(1));
|
||||
if (N1.getOperand(1) == N2.getOperand(1))
|
||||
|
@ -415,6 +417,35 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, SDOperand N1,
|
|||
}
|
||||
}
|
||||
|
||||
// Simplify (X+Z) == X --> Z == 0
|
||||
if (N1.getOperand(0) == N2)
|
||||
return getSetCC(Cond, N1.getOperand(1),
|
||||
getConstant(0, N1.getValueType()));
|
||||
if (N1.getOperand(1) == N2) {
|
||||
if (isCommutativeBinOp(N1.getOpcode()))
|
||||
return getSetCC(Cond, N1.getOperand(0),
|
||||
getConstant(0, N1.getValueType()));
|
||||
else {
|
||||
assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!");
|
||||
// (Z-X) == X --> Z == X<<1
|
||||
return getSetCC(Cond, N1.getOperand(0),
|
||||
getNode(ISD::SHL, N2.getValueType(),
|
||||
N2, getConstant(1, MVT::i8)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (N2.getOpcode() == ISD::ADD || N2.getOpcode() == ISD::SUB ||
|
||||
N2.getOpcode() == ISD::XOR) {
|
||||
// Simplify X == (X+Z) --> Z == 0
|
||||
if (N2.getOperand(0) == N1)
|
||||
return getSetCC(Cond, N2.getOperand(1),
|
||||
getConstant(0, N2.getValueType()));
|
||||
else if (N2.getOperand(1) == N1)
|
||||
return getSetCC(Cond, N2.getOperand(0),
|
||||
getConstant(0, N2.getValueType()));
|
||||
}
|
||||
}
|
||||
|
||||
SetCCSDNode *&N = SetCCs[std::make_pair(std::make_pair(N1, N2), Cond)];
|
||||
if (N) return SDOperand(N, 0);
|
||||
|
|
Loading…
Reference in New Issue