aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-12-14 19:05:06 +0000
committerChris Lattner <sabre@nondot.org>2005-12-14 19:05:06 +0000
commitad25d4e2df3fe01541d62ab0fd22c7de22ce3a42 (patch)
treeae4728bc982f18beb5105dd31e0478c3f894b5f1
parent6860f6a01ccc71d7cad61de506e0cf8ecb8ca146 (diff)
Fix the (zext (zextload)) case to trigger, similarly for sign extends.
Allow (zext (truncate)) to apply after legalize if the target supports AND (which all do). This compiles short %foo() { %tmp.0 = load ubyte* %X ; <ubyte> [#uses=1] %tmp.3 = cast ubyte %tmp.0 to short ; <short> [#uses=1] ret short %tmp.3 } to: _foo: movzbl _X, %eax ret instead of: _foo: movzbl _X, %eax movzbl %al, %eax ret thanks to Evan for pointing this out. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24709 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp35
1 files changed, 28 insertions, 7 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index c7cc6916ab..8077709c94 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -1543,9 +1543,6 @@ SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
// fold (sext (sext x)) -> (sext x)
if (N0.getOpcode() == ISD::SIGN_EXTEND)
return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0));
- // fold (sext (sextload x)) -> (sextload x)
- if (N0.getOpcode() == ISD::SEXTLOAD && VT == N0.getValueType())
- return N0;
// fold (sext (truncate x)) -> (sextinreg x) iff x size == sext size.
if (N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getValueType() == VT&&
(!AfterLegalize ||
@@ -1562,6 +1559,20 @@ SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
ExtLoad.getValue(1));
return SDOperand();
}
+
+ // fold (sext (sextload x)) -> (sext (truncate (sextload x)))
+ // fold (sext ( extload x)) -> (sext (truncate (sextload x)))
+ if ((N0.getOpcode() == ISD::SEXTLOAD || N0.getOpcode() == ISD::EXTLOAD) &&
+ N0.hasOneUse()) {
+ SDOperand ExtLoad = DAG.getNode(ISD::SEXTLOAD, VT, N0.getOperand(0),
+ N0.getOperand(1), N0.getOperand(2),
+ N0.getOperand(3));
+ WorkList.push_back(N);
+ CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
+ ExtLoad.getValue(1));
+ return SDOperand();
+ }
+
return SDOperand();
}
@@ -1576,12 +1587,9 @@ SDOperand DAGCombiner::visitZERO_EXTEND(SDNode *N) {
// fold (zext (zext x)) -> (zext x)
if (N0.getOpcode() == ISD::ZERO_EXTEND)
return DAG.getNode(ISD::ZERO_EXTEND, VT, N0.getOperand(0));
- // fold (zext (zextload x)) -> (zextload x)
- if (N0.getOpcode() == ISD::ZEXTLOAD && VT == N0.getValueType())
- return N0;
// fold (zext (truncate x)) -> (zextinreg x) iff x size == zext size.
if (N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getValueType() == VT&&
- !AfterLegalize)
+ (!AfterLegalize || TLI.isOperationLegal(ISD::AND, N0.getValueType())))
return DAG.getZeroExtendInReg(N0.getOperand(0), N0.getValueType());
// fold (zext (load x)) -> (zext (truncate (zextload x)))
if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse()) {
@@ -1593,6 +1601,19 @@ SDOperand DAGCombiner::visitZERO_EXTEND(SDNode *N) {
ExtLoad.getValue(1));
return SDOperand();
}
+
+ // fold (zext (zextload x)) -> (zext (truncate (zextload x)))
+ // fold (zext ( extload x)) -> (zext (truncate (zextload x)))
+ if ((N0.getOpcode() == ISD::ZEXTLOAD || N0.getOpcode() == ISD::EXTLOAD) &&
+ N0.hasOneUse()) {
+ SDOperand ExtLoad = DAG.getNode(ISD::ZEXTLOAD, VT, N0.getOperand(0),
+ N0.getOperand(1), N0.getOperand(2),
+ N0.getOperand(3));
+ WorkList.push_back(N);
+ CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
+ ExtLoad.getValue(1));
+ return SDOperand();
+ }
return SDOperand();
}