diff options
author | Chris Lattner <sabre@nondot.org> | 2006-02-02 07:17:31 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-02-02 07:17:31 +0000 |
commit | 3603cd62aed5cc54ec626848d0195eed2958312a (patch) | |
tree | 1d795d853b1426f4b3154a1a110204ff77b0d3a6 /lib/CodeGen/SelectionDAG/DAGCombiner.cpp | |
parent | 9a06cce0f2088a298f357b933fb7d8e268f6ca52 (diff) |
Turn any_extend nodes into zero_extend nodes when it allows us to remove an
and instruction. This allows us to compile stuff like this:
bool %X(int %X) {
%Y = add int %X, 14
%Z = setne int %Y, 12345
ret bool %Z
}
to this:
_X:
cmpl $12331, 4(%esp)
setne %al
movzbl %al, %eax
ret
instead of this:
_X:
cmpl $12331, 4(%esp)
setne %al
movzbl %al, %eax
andl $1, %eax
ret
This occurs quite a bit with the X86 backend. For example, 25 times in
lambda, 30 times in 177.mesa, 14 times in galgel, 70 times in fma3d,
25 times in vpr, several hundred times in gcc, ~45 times in crafty,
~60 times in parser, ~140 times in eon, 110 times in perlbmk, 55 on gap,
16 times on bzip2, 14 times on twolf, and 1-2 times in many other SPEC2K
programs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25901 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d57400bf4b..f79f783214 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -889,6 +889,19 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { if (ConstantSDNode *ORI = dyn_cast<ConstantSDNode>(N0.getOperand(1))) if ((ORI->getValue() & N1C->getValue()) == N1C->getValue()) return N1; + // fold (and (any_ext V), c) -> (zero_ext V) if 'and' only clears top bits. + if (N1C && N0.getOpcode() == ISD::ANY_EXTEND) { + unsigned InBits = MVT::getSizeInBits(N0.getOperand(0).getValueType()); + if (TLI.MaskedValueIsZero(N0.getOperand(0), + ~N1C->getValue() & ((1ULL << InBits)-1))) { + // We actually want to replace all uses of the any_extend with the + // zero_extend, to avoid duplicating things. This will later cause this + // AND to be folded. + CombineTo(N0.Val, DAG.getNode(ISD::ZERO_EXTEND, N0.getValueType(), + N0.getOperand(0))); + return SDOperand(); + } + } // fold (and (setcc x), (setcc y)) -> (setcc (and x, y)) if (isSetCCEquivalent(N0, LL, LR, CC0) && isSetCCEquivalent(N1, RL, RR, CC1)){ ISD::CondCode Op0 = cast<CondCodeSDNode>(CC0)->get(); |