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,23 +398,54 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, SDOperand N1,
|
||||||
Cond = UOF == 0 ? ISD::SETUO : ISD::SETO;
|
Cond = UOF == 0 ? ISD::SETUO : ISD::SETO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simplify (X+Y) == (X+Z) --> Y == Z
|
|
||||||
if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
|
if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
|
||||||
N1.getOpcode() == N2.getOpcode() && MVT::isInteger(N1.getValueType()))
|
MVT::isInteger(N1.getValueType())) {
|
||||||
if (N1.getOpcode() == ISD::ADD || N1.getOpcode() == ISD::SUB) {
|
if (N1.getOpcode() == ISD::ADD || N1.getOpcode() == ISD::SUB ||
|
||||||
if (N1.getOperand(0) == N2.getOperand(0))
|
N1.getOpcode() == ISD::XOR) {
|
||||||
return getSetCC(Cond, N1.getOperand(1), N2.getOperand(1));
|
// Simplify (X+Y) == (X+Z) --> Y == Z
|
||||||
if (N1.getOperand(1) == N2.getOperand(1))
|
if (N1.getOpcode() == N2.getOpcode()) {
|
||||||
return getSetCC(Cond, N1.getOperand(0), N2.getOperand(0));
|
if (N1.getOperand(0) == N2.getOperand(0))
|
||||||
if (isCommutativeBinOp(N1.getOpcode())) {
|
|
||||||
// If X op Y == Y op X, try other combinations.
|
|
||||||
if (N1.getOperand(0) == N2.getOperand(1))
|
|
||||||
return getSetCC(Cond, N1.getOperand(1), N2.getOperand(0));
|
|
||||||
if (N1.getOperand(1) == N2.getOperand(0))
|
|
||||||
return getSetCC(Cond, N1.getOperand(1), N2.getOperand(1));
|
return getSetCC(Cond, N1.getOperand(1), N2.getOperand(1));
|
||||||
|
if (N1.getOperand(1) == N2.getOperand(1))
|
||||||
|
return getSetCC(Cond, N1.getOperand(0), N2.getOperand(0));
|
||||||
|
if (isCommutativeBinOp(N1.getOpcode())) {
|
||||||
|
// If X op Y == Y op X, try other combinations.
|
||||||
|
if (N1.getOperand(0) == N2.getOperand(1))
|
||||||
|
return getSetCC(Cond, N1.getOperand(1), N2.getOperand(0));
|
||||||
|
if (N1.getOperand(1) == N2.getOperand(0))
|
||||||
|
return getSetCC(Cond, N1.getOperand(1), N2.getOperand(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)];
|
SetCCSDNode *&N = SetCCs[std::make_pair(std::make_pair(N1, N2), Cond)];
|
||||||
if (N) return SDOperand(N, 0);
|
if (N) return SDOperand(N, 0);
|
||||||
|
|
Loading…
Reference in New Issue