Sign-extend rather than zero-extend when promoting
authorDuncan Sands <baldrick@free.fr>
Fri, 7 Nov 2008 20:13:04 +0000 (20:13 +0000)
committerDuncan Sands <baldrick@free.fr>
Fri, 7 Nov 2008 20:13:04 +0000 (20:13 +0000)
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

include/llvm/CodeGen/SelectionDAGNodes.h
lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

index 7c78f6ab3758b0f0acf5d60141734f1941c4e7d6..3d5e68fecf54f1698974c0d17c6377bff0ecda43 100644 (file)
@@ -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
index 653614379dfd2b4be528f0e16cccbde77276e93a..9bd8bb521b7d89f733c5380d800574ea15179ce8 100644 (file)
@@ -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,