aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2008-11-07 20:13:04 +0000
committerDuncan Sands <baldrick@free.fr>2008-11-07 20:13:04 +0000
commit47b3417cf0d90724f9dab71aae4c7204e46847b6 (patch)
tree287a1dce0afcde077872973c06624c5a3a65ea36
parente5f4de42b5d26f60cec6fab0482eaf579246b218 (diff)
downloadexternal_llvm-47b3417cf0d90724f9dab71aae4c7204e46847b6.zip
external_llvm-47b3417cf0d90724f9dab71aae4c7204e46847b6.tar.gz
external_llvm-47b3417cf0d90724f9dab71aae4c7204e46847b6.tar.bz2
Sign-extend rather than zero-extend when promoting
the condition for a BRCOND, according to what is returned by getSetCCResultContents. Since all targets return the same thing (ZeroOrOneSetCCResult), this should be harmless! The point is that all over the place the result of SETCC is fed directly into BRCOND. On machines for which getSetCCResultContents returns ZeroOrNegativeOneSetCCResult, this is a sign-extended boolean. So it seems dangerous to also feed BRCOND zero-extended booleans in some circumstances - for example, when promoting the condition. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58861 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h9
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp25
2 files changed, 24 insertions, 10 deletions
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 7c78f6a..3d5e68f 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -468,10 +468,11 @@ namespace ISD {
// BR_JT - Jumptable branch. The first operand is the chain, the second
// is the jumptable index, the last one is the jumptable entry index.
BR_JT,
-
- // BRCOND - Conditional branch. The first operand is the chain,
- // the second is the condition, the third is the block to branch
- // to if the condition is true.
+
+ // BRCOND - Conditional branch. The first operand is the chain, the
+ // second is the condition, the third is the block to branch to if the
+ // condition is true. If the type of the condition is not i1, then the
+ // high bits must conform to getSetCCResultContents.
BRCOND,
// BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 6536143..9bd8bb5 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -696,12 +696,25 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) {
assert(OpNo == 1 && "only know how to promote condition");
SDValue Cond = GetPromotedInteger(N->getOperand(1)); // Promote condition.
- // The top bits of the promoted condition are not necessarily zero, ensure
- // that the value is properly zero extended.
- unsigned BitWidth = Cond.getValueSizeInBits();
- if (!DAG.MaskedValueIsZero(Cond,
- APInt::getHighBitsSet(BitWidth, BitWidth-1)))
- Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
+ // Make sure the extra bits coming from type promotion conform to
+ // getSetCCResultContents.
+ unsigned CondBits = Cond.getValueSizeInBits();
+ switch (TLI.getSetCCResultContents()) {
+ default:
+ assert(false && "Unknown SetCCResultValue!");
+ case TargetLowering::UndefinedSetCCResult:
+ // The promoted value, which may contain rubbish in the upper bits, is fine.
+ break;
+ case TargetLowering::ZeroOrOneSetCCResult:
+ if (!DAG.MaskedValueIsZero(Cond,APInt::getHighBitsSet(CondBits,CondBits-1)))
+ Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
+ break;
+ case TargetLowering::ZeroOrNegativeOneSetCCResult:
+ if (DAG.ComputeNumSignBits(Cond) != CondBits)
+ Cond = DAG.getNode(ISD::SIGN_EXTEND_INREG, Cond.getValueType(), Cond,
+ DAG.getValueType(MVT::i1));
+ break;
+ }
// The chain (Op#0) and basic block destination (Op#2) are always legal types.
return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), Cond,