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:
Chris Lattner 2005-01-10 02:03:02 +00:00
parent 00c231baa7
commit 41b764144d
1 changed files with 43 additions and 12 deletions

View File

@ -398,23 +398,54 @@ 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) {
if (N1.getOperand(0) == N2.getOperand(0))
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))
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))
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)];
if (N) return SDOperand(N, 0);