summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/X86ISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/X86/X86ISelLowering.cpp')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp15
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");
OpenPOWER on IntegriCloud