diff options
| author | Pete Cooper <peter_cooper@apple.com> | 2012-04-03 22:57:55 +0000 | 
|---|---|---|
| committer | Pete Cooper <peter_cooper@apple.com> | 2012-04-03 22:57:55 +0000 | 
| commit | 9511ec86f96399cd852565e61dbc44dc8b26e78f (patch) | |
| tree | ae803e416ea9c151c1e102f9f6d19b3a37c7eb13 /llvm | |
| parent | b98934cf72bc190fb8ba1830950a441903220e3f (diff) | |
| download | bcm5719-llvm-9511ec86f96399cd852565e61dbc44dc8b26e78f.tar.gz bcm5719-llvm-9511ec86f96399cd852565e61dbc44dc8b26e78f.zip  | |
Add VSELECT to LegalizeVectorTypes::ScalariseVectorResult.  Previously it would crash if it encountered a 1 element VSELECT.  Solution is slightly more complicated than just creating a SELET as we have to mask or sign extend the vector condition if it had different boolean contents from the scalar condition.  Fixes <rdar://problem/11178095>
llvm-svn: 153976
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h | 1 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp | 33 | ||||
| -rw-r--r-- | llvm/test/CodeGen/Generic/select.ll | 8 | 
3 files changed, 42 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 69c21000015..e8664458e9a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -521,6 +521,7 @@ private:    SDValue ScalarizeVecRes_LOAD(LoadSDNode *N);    SDValue ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N);    SDValue ScalarizeVecRes_SIGN_EXTEND_INREG(SDNode *N); +  SDValue ScalarizeVecRes_VSELECT(SDNode *N);    SDValue ScalarizeVecRes_SELECT(SDNode *N);    SDValue ScalarizeVecRes_SELECT_CC(SDNode *N);    SDValue ScalarizeVecRes_SETCC(SDNode *N); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index a8aee122788..aa92cc3638b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -58,6 +58,7 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {    case ISD::LOAD:           R = ScalarizeVecRes_LOAD(cast<LoadSDNode>(N));break;    case ISD::SCALAR_TO_VECTOR:  R = ScalarizeVecRes_SCALAR_TO_VECTOR(N); break;    case ISD::SIGN_EXTEND_INREG: R = ScalarizeVecRes_InregOp(N); break; +  case ISD::VSELECT:           R = ScalarizeVecRes_VSELECT(N); break;    case ISD::SELECT:            R = ScalarizeVecRes_SELECT(N); break;    case ISD::SELECT_CC:         R = ScalarizeVecRes_SELECT_CC(N); break;    case ISD::SETCC:             R = ScalarizeVecRes_SETCC(N); break; @@ -226,6 +227,38 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N) {    return InOp;  } +SDValue DAGTypeLegalizer::ScalarizeVecRes_VSELECT(SDNode *N) { +  SDValue Cond = GetScalarizedVector(N->getOperand(0)); +  SDValue LHS = GetScalarizedVector(N->getOperand(1)); +  TargetLowering::BooleanContent ScalarBool = TLI.getBooleanContents(false); +  TargetLowering::BooleanContent VecBool = TLI.getBooleanContents(true); +  if (ScalarBool != VecBool) { +    EVT CondVT = Cond.getValueType(); +    switch (ScalarBool) { +      default: llvm_unreachable("Unknown boolean content enum"); +      case TargetLowering::UndefinedBooleanContent: +        break; +      case TargetLowering::ZeroOrOneBooleanContent: +        assert(VecBool == TargetLowering::UndefinedBooleanContent || +               VecBool == TargetLowering::ZeroOrNegativeOneBooleanContent); +        // Vector read from all ones, scalar expects a single 1 so mask. +        Cond = DAG.getNode(ISD::AND, N->getDebugLoc(), CondVT, +                           Cond, DAG.getConstant(1, CondVT)); +        break; +      case TargetLowering::ZeroOrNegativeOneBooleanContent: +        assert(VecBool == TargetLowering::UndefinedBooleanContent || +               VecBool == TargetLowering::ZeroOrOneBooleanContent); +        // Vector reads from a one, scalar from all ones so sign extend. +        Cond = DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), CondVT, +                           Cond, DAG.getValueType(MVT::i1)); +        break; +    } +  } +  return DAG.getNode(ISD::SELECT, N->getDebugLoc(), +                     LHS.getValueType(), Cond, LHS, +                     GetScalarizedVector(N->getOperand(2))); +} +  SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT(SDNode *N) {    SDValue LHS = GetScalarizedVector(N->getOperand(1));    return DAG.getNode(ISD::SELECT, N->getDebugLoc(), diff --git a/llvm/test/CodeGen/Generic/select.ll b/llvm/test/CodeGen/Generic/select.ll index 63052c1a284..77636eb6e61 100644 --- a/llvm/test/CodeGen/Generic/select.ll +++ b/llvm/test/CodeGen/Generic/select.ll @@ -185,3 +185,11 @@ define i32 @checkFoldGEP(%Domain* %D, i64 %idx) {          ret i32 %reg820  } +; Test case for scalarising a 1 element vselect +; +define <1 x i32> @checkScalariseVSELECT(<1 x i32> %a, <1 x i32> %b) { +        %cond = icmp uge <1 x i32> %a, %b +        %s = select <1 x i1> %cond, <1 x i32> %a, <1 x i32> %b +        ret <1 x i32> %s +} +  | 

