mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Don't bother sign/zext_inreg'ing the result of an and operation if we know
the result does change as a result of the extend. This improves codegen for Alpha on this testcase: int %a(ushort* %i) { %tmp.1 = load ushort* %i %tmp.2 = cast ushort %tmp.1 to int %tmp.4 = and int %tmp.2, 1 ret int %tmp.4 } Generating: a: ldgp $29, 0($27) ldwu $0,0($16) and $0,1,$0 ret $31,($26),1 instead of: a: ldgp $29, 0($27) ldwu $0,0($16) and $0,1,$0 addl $0,0,$0 ret $31,($26),1 btw, alpha really should switch to livein/outs for args :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21213 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
01ff7216dd
commit
2bb6f41282
@ -1119,6 +1119,25 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
if (Opcode == ISD::SIGN_EXTEND_INREG) return N1;
|
||||
break;
|
||||
}
|
||||
|
||||
// If we are sign extending the result of an (and X, C) operation, and we
|
||||
// know the extended bits are zeros already, don't do the extend.
|
||||
if (N1.getOpcode() == ISD::AND)
|
||||
if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getOperand(1))) {
|
||||
uint64_t Mask = N1C->getValue();
|
||||
unsigned NumBits = MVT::getSizeInBits(EVT);
|
||||
if (Opcode == ISD::ZERO_EXTEND_INREG) {
|
||||
if ((Mask & (~0ULL << NumBits)) == 0)
|
||||
return N1;
|
||||
else
|
||||
return getNode(ISD::AND, VT, N1.getOperand(0),
|
||||
getConstant(Mask & (~0ULL >> (64-NumBits)), VT));
|
||||
} else {
|
||||
assert(Opcode == ISD::SIGN_EXTEND_INREG);
|
||||
if ((Mask & (~0ULL << (NumBits-1))) == 0)
|
||||
return N1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user