diff options
Diffstat (limited to 'lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
| -rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 32 | 
1 files changed, 23 insertions, 9 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d888676583f3..5ecc6da32144 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -6198,13 +6198,27 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {        }      } -    // sext(setcc x, y, cc) -> (select (setcc x, y, cc), -1, 0) -    unsigned ElementWidth = VT.getScalarType().getSizeInBits(); +    // sext(setcc x, y, cc) -> (select (setcc x, y, cc), T, 0) +    // Here, T can be 1 or -1, depending on the type of the setcc and +    // getBooleanContents(). +    unsigned SetCCWidth = N0.getValueType().getScalarSizeInBits(); +      SDLoc DL(N); -    SDValue NegOne = -      DAG.getConstant(APInt::getAllOnesValue(ElementWidth), DL, VT); +    // To determine the "true" side of the select, we need to know the high bit +    // of the value returned by the setcc if it evaluates to true. +    // If the type of the setcc is i1, then the true case of the select is just +    // sext(i1 1), that is, -1. +    // If the type of the setcc is larger (say, i8) then the value of the high +    // bit depends on getBooleanContents(). So, ask TLI for a real "true" value +    // of the appropriate width. +    SDValue ExtTrueVal = +        (SetCCWidth == 1) +            ? DAG.getConstant(APInt::getAllOnesValue(VT.getScalarSizeInBits()), +                              DL, VT) +            : TLI.getConstTrueVal(DAG, VT, DL); +      if (SDValue SCC = SimplifySelectCC( -            DL, N0.getOperand(0), N0.getOperand(1), NegOne, +            DL, N0.getOperand(0), N0.getOperand(1), ExtTrueVal,              DAG.getConstant(0, DL, VT),              cast<CondCodeSDNode>(N0.getOperand(2))->get(), true))        return SCC; @@ -6215,10 +6229,10 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {            TLI.isOperationLegal(ISD::SETCC, N0.getOperand(0).getValueType())) {          SDLoc DL(N);          ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get(); -        SDValue SetCC = DAG.getSetCC(DL, SetCCVT, -                                     N0.getOperand(0), N0.getOperand(1), CC); -        return DAG.getSelect(DL, VT, SetCC, -                             NegOne, DAG.getConstant(0, DL, VT)); +        SDValue SetCC = +            DAG.getSetCC(DL, SetCCVT, N0.getOperand(0), N0.getOperand(1), CC); +        return DAG.getSelect(DL, VT, SetCC, ExtTrueVal, +                             DAG.getConstant(0, DL, VT));        }      }    }  | 
