diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86ISelLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index ac482336881..b7a8d6f1775 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -24881,15 +24881,16 @@ static SDValue LowerRotate(SDValue Op, const X86Subtarget &Subtarget, return SignBitSelect(VT, Amt, M, R); } + // ISD::ROT* uses modulo rotate amounts. + Amt = DAG.getNode(ISD::AND, DL, VT, Amt, + DAG.getConstant(EltSizeInBits - 1, DL, VT)); + bool ConstantAmt = ISD::isBuildVectorOfConstantSDNodes(Amt.getNode()); bool LegalVarShifts = SupportedVectorVarShift(VT, Subtarget, ISD::SHL) && SupportedVectorVarShift(VT, Subtarget, ISD::SRL); - // Rotate by splat - expand back to shifts. - // Best to fallback for all supported variable shifts. - // AVX2 - best to fallback for non-constants as well. - // TODO - legalizers should be able to handle this. - // TODO - We need explicit modulo rotation amounts. + // Fallback for splats + all supported variable shifts. + // Fallback for non-constants AVX2 vXi16 as well. if (LegalVarShifts || (Subtarget.hasAVX2() && !ConstantAmt) || DAG.isSplatValue(Amt)) { SDValue AmtR = DAG.getConstant(EltSizeInBits, DL, VT); @@ -24899,10 +24900,6 @@ static SDValue LowerRotate(SDValue Op, const X86Subtarget &Subtarget, return DAG.getNode(ISD::OR, DL, VT, SHL, SRL); } - // ISD::ROT* uses modulo rotate amounts. - Amt = DAG.getNode(ISD::AND, DL, VT, Amt, - DAG.getConstant(EltSizeInBits - 1, DL, VT)); - // As with shifts, convert the rotation amount to a multiplication factor. SDValue Scale = convertShiftLeftToScale(Amt, DL, Subtarget, DAG); assert(Scale && "Failed to convert ROTL amount to scale"); |

