mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-21 03:05:26 -04:00
[X86][SSE] Disable shouldFoldConstantShiftPairToMask for btver1/btver2 targets (PR40758)
As detailed on PR40758, Bobcat/Jaguar can perform vector immediate shifts on the same pipes as vector ANDs with the same latency - so it doesn't make sense to replace a shl+lshr with a shift+and pair as it requires an additional mask (with the extra constant pool, loading and register pressure costs). Differential Revision: https://reviews.llvm.org/D61068 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@359293 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -6882,6 +6882,8 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
|
||||
// (and (srl x, (sub c1, c2), MASK)
|
||||
// Only fold this if the inner shift has no other uses -- if it does, folding
|
||||
// this will increase the total number of instructions.
|
||||
// TODO - drop hasOneUse requirement if c1 == c2?
|
||||
// TODO - support non-uniform vector shift amounts.
|
||||
if (N1C && N0.getOpcode() == ISD::SRL && N0.hasOneUse() &&
|
||||
TLI.shouldFoldConstantShiftPairToMask(N, Level)) {
|
||||
if (ConstantSDNode *N0C1 = isConstOrConstSplat(N0.getOperand(1))) {
|
||||
@@ -7188,6 +7190,7 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
|
||||
}
|
||||
|
||||
// fold (srl (shl x, c), c) -> (and x, cst2)
|
||||
// TODO - (srl (shl x, c1), c2).
|
||||
if (N0.getOpcode() == ISD::SHL && N0.getOperand(1) == N1 &&
|
||||
isConstantOrConstantVector(N1, /* NoOpaques */ true)) {
|
||||
SDLoc DL(N);
|
||||
|
||||
@@ -424,6 +424,11 @@ def FeatureFastHorizontalOps
|
||||
"Prefer horizontal vector math instructions (haddp, phsub, etc.) over "
|
||||
"normal vector instructions with shuffles", [FeatureSSE3]>;
|
||||
|
||||
def FeatureFastVectorShiftMasks
|
||||
: SubtargetFeature<
|
||||
"fast-vector-shift-masks", "HasFastVectorShiftMasks", "true",
|
||||
"Prefer a left/right vector logical shift pair over a shift+and pair">;
|
||||
|
||||
// Merge branches using three-way conditional code.
|
||||
def FeatureMergeToThreeWayBranch : SubtargetFeature<"merge-to-threeway-branch",
|
||||
"ThreewayBranchProfitable", "true",
|
||||
@@ -775,7 +780,8 @@ def ProcessorFeatures {
|
||||
FeaturePOPCNT,
|
||||
FeatureSlowSHLD,
|
||||
FeatureLAHFSAHF,
|
||||
FeatureFast15ByteNOP];
|
||||
FeatureFast15ByteNOP,
|
||||
FeatureFastVectorShiftMasks];
|
||||
list<SubtargetFeature> BtVer1Features = BtVer1InheritableFeatures;
|
||||
|
||||
// Jaguar
|
||||
|
||||
@@ -5013,7 +5013,18 @@ bool X86TargetLowering::hasAndNot(SDValue Y) const {
|
||||
|
||||
bool X86TargetLowering::shouldFoldConstantShiftPairToMask(
|
||||
const SDNode *N, CombineLevel Level) const {
|
||||
// TODO - some targets prefer immediate vector shifts to shift+mask.
|
||||
assert((N->getOpcode() == ISD::SHL &&
|
||||
N->getOperand(0).getOpcode() == ISD::SRL) ||
|
||||
(N->getOpcode() == ISD::SRL &&
|
||||
N->getOperand(0).getOpcode() == ISD::SHL) &&
|
||||
"Expected shift-shift mask");
|
||||
|
||||
if (Subtarget.hasFastVectorShiftMasks() && N->getValueType(0).isVector()) {
|
||||
// Only fold if the shift values are equal - so it folds to AND.
|
||||
// TODO - we should fold if either is non-uniform but we don't do the
|
||||
// fold for non-splats yet.
|
||||
return N->getOperand(1) == N->getOperand(0).getOperand(1);
|
||||
}
|
||||
return TargetLoweringBase::shouldFoldConstantShiftPairToMask(N, Level);
|
||||
}
|
||||
|
||||
|
||||
@@ -393,6 +393,9 @@ protected:
|
||||
/// Try harder to combine to horizontal vector ops if they are fast.
|
||||
bool HasFastHorizontalOps = false;
|
||||
|
||||
/// Prefer a left/right vector logical shifts pair over a shift+and pair.
|
||||
bool HasFastVectorShiftMasks = false;
|
||||
|
||||
/// Use a retpoline thunk rather than indirect calls to block speculative
|
||||
/// execution.
|
||||
bool UseRetpolineIndirectCalls = false;
|
||||
@@ -644,6 +647,7 @@ public:
|
||||
bool hasFastSHLDRotate() const { return HasFastSHLDRotate; }
|
||||
bool hasFastBEXTR() const { return HasFastBEXTR; }
|
||||
bool hasFastHorizontalOps() const { return HasFastHorizontalOps; }
|
||||
bool hasFastVectorShiftMasks() const { return HasFastVectorShiftMasks; }
|
||||
bool hasMacroFusion() const { return HasMacroFusion; }
|
||||
bool hasBranchFusion() const { return HasBranchFusion; }
|
||||
bool hasERMSB() const { return HasERMSB; }
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+sse2 | FileCheck %s
|
||||
; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+sse2 | FileCheck %s --check-prefixes=CHECK,MASK
|
||||
; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+sse2,+fast-vector-shift-masks | FileCheck %s --check-prefixes=CHECK,SHIFT
|
||||
; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=btver1 | FileCheck %s --check-prefixes=CHECK,SHIFT
|
||||
|
||||
; SSE2 Logical Shift Left
|
||||
|
||||
@@ -300,11 +302,17 @@ define <4 x i32> @shl_sra_v4i32(<4 x i32> %x) nounwind {
|
||||
}
|
||||
|
||||
define <4 x i32> @shl_srl_v4i32(<4 x i32> %x) nounwind {
|
||||
; CHECK-LABEL: shl_srl_v4i32:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: pslld $3, %xmm0
|
||||
; CHECK-NEXT: pand {{.*}}(%rip), %xmm0
|
||||
; CHECK-NEXT: retq
|
||||
; MASK-LABEL: shl_srl_v4i32:
|
||||
; MASK: # %bb.0:
|
||||
; MASK-NEXT: pslld $3, %xmm0
|
||||
; MASK-NEXT: pand {{.*}}(%rip), %xmm0
|
||||
; MASK-NEXT: retq
|
||||
;
|
||||
; SHIFT-LABEL: shl_srl_v4i32:
|
||||
; SHIFT: # %bb.0:
|
||||
; SHIFT-NEXT: psrld $2, %xmm0
|
||||
; SHIFT-NEXT: pslld $5, %xmm0
|
||||
; SHIFT-NEXT: retq
|
||||
%shl0 = lshr <4 x i32> %x, <i32 2, i32 2, i32 2, i32 2>
|
||||
%shl1 = shl <4 x i32> %shl0, <i32 5, i32 5, i32 5, i32 5>
|
||||
ret <4 x i32> %shl1
|
||||
|
||||
Reference in New Issue
Block a user