[llvm] r288844 - [X86] Prefer reduced width multiplication over pmulld on Silvermont
Zvi Rackover via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 6 11:35:21 PST 2016
Author: zvi
Date: Tue Dec 6 13:35:20 2016
New Revision: 288844
URL: http://llvm.org/viewvc/llvm-project?rev=288844&view=rev
Log:
[X86] Prefer reduced width multiplication over pmulld on Silvermont
Summary:
Prefer expansions such as: pmullw,pmulhw,unpacklwd,unpackhwd over pmulld.
On Silvermont [source: Optimization Reference Manual]:
PMULLD has a throughput of 1/11 [instruction/cycles].
PMULHUW/PMULHW/PMULLW have a throughput of 1/2 [instruction/cycles].
Fixes pr31202.
Analysis of this issue was done by Fahana Aleen.
Reviewers: wmi, delena, mkuper
Subscribers: RKSimon, llvm-commits
Differential Revision: https://reviews.llvm.org/D27203
Added:
llvm/trunk/test/CodeGen/X86/slow-pmulld.ll (with props)
Modified:
llvm/trunk/lib/Target/X86/X86.td
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/lib/Target/X86/X86Subtarget.cpp
llvm/trunk/lib/Target/X86/X86Subtarget.h
Modified: llvm/trunk/lib/Target/X86/X86.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.td?rev=288844&r1=288843&r2=288844&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86.td (original)
+++ llvm/trunk/lib/Target/X86/X86.td Tue Dec 6 13:35:20 2016
@@ -99,6 +99,8 @@ def FeatureSlowBTMem : SubtargetFeature<
"Bit testing of memory is slow">;
def FeatureSlowSHLD : SubtargetFeature<"slow-shld", "IsSHLDSlow", "true",
"SHLD instruction is slow">;
+def FeatureSlowPMULLD : SubtargetFeature<"slow-pmulld", "IsPMULLDSlow", "true",
+ "PMULLD instruction is slow">;
// FIXME: This should not apply to CPUs that do not have SSE.
def FeatureSlowUAMem16 : SubtargetFeature<"slow-unaligned-mem-16",
"IsUAMem16Slow", "true",
@@ -403,6 +405,7 @@ class SilvermontProc<string Name> : Proc
FeatureSlowLEA,
FeatureSlowIncDec,
FeatureSlowBTMem,
+ FeatureSlowPMULLD,
FeatureLAHFSAHF
]>;
def : SilvermontProc<"silvermont">;
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=288844&r1=288843&r2=288844&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Dec 6 13:35:20 2016
@@ -29302,10 +29302,17 @@ static bool canReduceVMulWidth(SDNode *N
/// generate pmullw+pmulhuw for it (MULU16 mode).
static SDValue reduceVMULWidth(SDNode *N, SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
- // pmulld is supported since SSE41. It is better to use pmulld
- // instead of pmullw+pmulhw.
+ // Check for legality
// pmullw/pmulhw are not supported by SSE.
- if (Subtarget.hasSSE41() || !Subtarget.hasSSE2())
+ if (!Subtarget.hasSSE2())
+ return SDValue();
+
+ // Check for profitability
+ // pmulld is supported since SSE41. It is better to use pmulld
+ // instead of pmullw+pmulhw, except for subtargets where pmulld is slower than
+ // the expansion.
+ bool OptForMinSize = DAG.getMachineFunction().getFunction()->optForMinSize();
+ if (Subtarget.hasSSE41() && (OptForMinSize || !Subtarget.isPMULLDSlow()))
return SDValue();
ShrinkMode Mode;
Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=288844&r1=288843&r2=288844&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Tue Dec 6 13:35:20 2016
@@ -228,6 +228,9 @@ void X86Subtarget::initSubtargetFeatures
else if (isTargetDarwin() || isTargetLinux() || isTargetSolaris() ||
isTargetKFreeBSD() || In64BitMode)
stackAlignment = 16;
+
+ assert((!isPMULLDSlow() || hasSSE41()) &&
+ "Feature Slow PMULLD can only be set on a subtarget with SSE4.1");
}
void X86Subtarget::initializeEnvironment() {
@@ -275,6 +278,7 @@ void X86Subtarget::initializeEnvironment
HasMWAITX = false;
HasMPX = false;
IsBTMemSlow = false;
+ IsPMULLDSlow = false;
IsSHLDSlow = false;
IsUAMem16Slow = false;
IsUAMem32Slow = false;
Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=288844&r1=288843&r2=288844&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86Subtarget.h (original)
+++ llvm/trunk/lib/Target/X86/X86Subtarget.h Tue Dec 6 13:35:20 2016
@@ -178,6 +178,10 @@ protected:
/// True if SHLD instructions are slow.
bool IsSHLDSlow;
+ /// True if the PMULLD instruction is slow compared to PMULLW/PMULHW and
+ // PMULUDQ.
+ bool IsPMULLDSlow;
+
/// True if unaligned memory accesses of 16-bytes are slow.
bool IsUAMem16Slow;
@@ -452,6 +456,7 @@ public:
bool hasMWAITX() const { return HasMWAITX; }
bool isBTMemSlow() const { return IsBTMemSlow; }
bool isSHLDSlow() const { return IsSHLDSlow; }
+ bool isPMULLDSlow() const { return IsPMULLDSlow; }
bool isUnalignedMem16Slow() const { return IsUAMem16Slow; }
bool isUnalignedMem32Slow() const { return IsUAMem32Slow; }
bool hasSSEUnalignedMem() const { return HasSSEUnalignedMem; }
Added: llvm/trunk/test/CodeGen/X86/slow-pmulld.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/slow-pmulld.ll?rev=288844&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/slow-pmulld.ll (added)
+++ llvm/trunk/test/CodeGen/X86/slow-pmulld.ll Tue Dec 6 13:35:20 2016
@@ -0,0 +1,71 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=i386-unknown-unknown -mcpu=silvermont | FileCheck %s --check-prefix=CHECK32
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=silvermont | FileCheck %s --check-prefix=CHECK64
+; RUN: llc < %s -mtriple=i386-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE4-32
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE4-64
+
+define <4 x i32> @foo(<4 x i8> %A) {
+; CHECK32-LABEL: foo:
+; CHECK32: # BB#0:
+; CHECK32-NEXT: pshufb {{.*#+}} xmm0 = xmm0[0],zero,xmm0[4],zero,xmm0[8],zero,xmm0[12],zero,xmm0[u,u,u,u,u,u,u,u]
+; CHECK32-NEXT: movdqa {{.*#+}} xmm1 = <18778,18778,18778,18778,u,u,u,u>
+; CHECK32-NEXT: movdqa %xmm0, %xmm2
+; CHECK32-NEXT: pmullw %xmm1, %xmm0
+; CHECK32-NEXT: pmulhw %xmm1, %xmm2
+; CHECK32-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3]
+; CHECK32-NEXT: retl
+;
+; CHECK64-LABEL: foo:
+; CHECK64: # BB#0:
+; CHECK64-NEXT: pshufb {{.*#+}} xmm0 = xmm0[0],zero,xmm0[4],zero,xmm0[8],zero,xmm0[12],zero,xmm0[u,u,u,u,u,u,u,u]
+; CHECK64-NEXT: movdqa {{.*#+}} xmm1 = <18778,18778,18778,18778,u,u,u,u>
+; CHECK64-NEXT: movdqa %xmm0, %xmm2
+; CHECK64-NEXT: pmullw %xmm1, %xmm0
+; CHECK64-NEXT: pmulhw %xmm1, %xmm2
+; CHECK64-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3]
+; CHECK64-NEXT: retq
+;
+; SSE4-32-LABEL: foo:
+; SSE4-32: # BB#0:
+; SSE4-32-NEXT: pand {{\.LCPI.*}}, %xmm0
+; SSE4-32-NEXT: pmulld {{\.LCPI.*}}, %xmm0
+; SSE4-32-NEXT: retl
+;
+; SSE4-64-LABEL: foo:
+; SSE4-64: # BB#0:
+; SSE4-64-NEXT: pand {{.*}}(%rip), %xmm0
+; SSE4-64-NEXT: pmulld {{.*}}(%rip), %xmm0
+; SSE4-64-NEXT: retq
+ %z = zext <4 x i8> %A to <4 x i32>
+ %m = mul nuw nsw <4 x i32> %z, <i32 18778, i32 18778, i32 18778, i32 18778>
+ ret <4 x i32> %m
+}
+
+define <4 x i32> @foo_os(<4 x i8> %A) minsize {
+; CHECK32-LABEL: foo_os:
+; CHECK32: # BB#0:
+; CHECK32-NEXT: pand {{\.LCPI.*}}, %xmm0
+; CHECK32-NEXT: pmulld {{\.LCPI.*}}, %xmm0
+; CHECK32-NEXT: retl
+;
+; CHECK64-LABEL: foo_os:
+; CHECK64: # BB#0:
+; CHECK64-NEXT: pand {{.*}}(%rip), %xmm0
+; CHECK64-NEXT: pmulld {{.*}}(%rip), %xmm0
+; CHECK64-NEXT: retq
+;
+; SSE4-32-LABEL: foo_os:
+; SSE4-32: # BB#0:
+; SSE4-32-NEXT: pand {{\.LCPI.*}}, %xmm0
+; SSE4-32-NEXT: pmulld {{\.LCPI.*}}, %xmm0
+; SSE4-32-NEXT: retl
+;
+; SSE4-64-LABEL: foo_os:
+; SSE4-64: # BB#0:
+; SSE4-64-NEXT: pand {{.*}}(%rip), %xmm0
+; SSE4-64-NEXT: pmulld {{.*}}(%rip), %xmm0
+; SSE4-64-NEXT: retq
+ %z = zext <4 x i8> %A to <4 x i32>
+ %m = mul nuw nsw <4 x i32> %z, <i32 18778, i32 18778, i32 18778, i32 18778>
+ ret <4 x i32> %m
+}
Propchange: llvm/trunk/test/CodeGen/X86/slow-pmulld.ll
------------------------------------------------------------------------------
svn:eol-style = native
More information about the llvm-commits
mailing list