]> granicus.if.org Git - llvm/commitdiff
[X86] Allow vpclmulqdq instructions to be commuted during isel to allow load folding.
authorCraig Topper <craig.topper@intel.com>
Tue, 21 Nov 2017 21:05:21 +0000 (21:05 +0000)
committerCraig Topper <craig.topper@intel.com>
Tue, 21 Nov 2017 21:05:21 +0000 (21:05 +0000)
The commuting patterns for the AVX version actually still had priority over the new patterns.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@318800 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86InstrSSE.td
test/CodeGen/X86/commute-clmul.ll

index ead8cb4ba001f5c12b40cb8b4db8b7e2c427c2d1..9d7b17c0453f0447846f5c33d2f37e2c4d8a993d 100644 (file)
@@ -7242,24 +7242,37 @@ def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
 // PCLMUL Instructions
 //===----------------------------------------------------------------------===//
 
+// Immediate transform to help with commuting.
+def PCLMULCommuteImm : SDNodeXForm<imm, [{
+  uint8_t Imm = N->getZExtValue();
+  return getI8Imm((uint8_t)((Imm >> 4) | (Imm << 4)), SDLoc(N));
+}]>;
+
 // SSE carry-less Multiplication instructions
-let Constraints = "$src1 = $dst", Predicates = [NoAVX, HasPCLMUL] in {
-  let isCommutable = 1 in
-  def PCLMULQDQrr : PCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
-            (ins VR128:$src1, VR128:$src2, u8imm:$src3),
-            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
-            [(set VR128:$dst,
-              (int_x86_pclmulqdq VR128:$src1, VR128:$src2, imm:$src3))],
-            IIC_SSE_PCLMULQDQ_RR>, Sched<[WriteCLMul]>;
-
-  def PCLMULQDQrm : PCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
-            (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
-            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
-            [(set VR128:$dst,
-               (int_x86_pclmulqdq VR128:$src1, (memopv2i64 addr:$src2),
-                imm:$src3))],
-            IIC_SSE_PCLMULQDQ_RR>, Sched<[WriteCLMulLd, ReadAfterLd]>;
-}
+let Predicates = [NoAVX, HasPCLMUL] in {
+  let Constraints = "$src1 = $dst" in {
+    let isCommutable = 1 in
+    def PCLMULQDQrr : PCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
+              (ins VR128:$src1, VR128:$src2, u8imm:$src3),
+              "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
+              [(set VR128:$dst,
+                (int_x86_pclmulqdq VR128:$src1, VR128:$src2, imm:$src3))],
+              IIC_SSE_PCLMULQDQ_RR>, Sched<[WriteCLMul]>;
+
+    def PCLMULQDQrm : PCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
+              (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
+              "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
+              [(set VR128:$dst,
+                 (int_x86_pclmulqdq VR128:$src1, (memopv2i64 addr:$src2),
+                  imm:$src3))],
+              IIC_SSE_PCLMULQDQ_RR>, Sched<[WriteCLMulLd, ReadAfterLd]>;
+  } // Constraints = "$src1 = $dst"
+
+  def : Pat<(int_x86_pclmulqdq (memopv2i64 addr:$src2), VR128:$src1,
+                                (i8 imm:$src3)),
+            (PCLMULQDQrm VR128:$src1, addr:$src2,
+                          (PCLMULCommuteImm imm:$src3))>;
+} // Predicates = [NoAVX, HasPCLMUL]
 
 // SSE aliases
 foreach HI = ["hq","lq"] in
@@ -7289,6 +7302,12 @@ multiclass vpclmulqdq<RegisterClass RC, X86MemOperand MemOp,
             [(set RC:$dst,
                (IntId RC:$src1, (LdFrag addr:$src2), imm:$src3))]>,
             Sched<[WriteCLMulLd, ReadAfterLd]>;
+
+  // We can commute a load in the first operand by swapping the sources and
+  // rotating the immediate.
+  def : Pat<(IntId (LdFrag addr:$src2), RC:$src1, (i8 imm:$src3)),
+            (!cast<Instruction>(NAME#"rm") RC:$src1, addr:$src2,
+                                           (PCLMULCommuteImm imm:$src3))>;
 }
 
 let Predicates = [HasAVX, NoVLX_Or_NoVPCLMULQDQ, HasPCLMUL] in
@@ -7321,28 +7340,6 @@ multiclass vpclmulqdq_aliases<string InstStr, RegisterClass RC,
 defm : vpclmulqdq_aliases<"VPCLMULQDQ", VR128, i128mem>;
 defm : vpclmulqdq_aliases<"VPCLMULQDQY", VR256, i256mem>;
 
-// Immediate transform to help with commuting.
-def PCLMULCommuteImm : SDNodeXForm<imm, [{
-  uint8_t Imm = N->getZExtValue();
-  return getI8Imm((uint8_t)((Imm >> 4) | (Imm << 4)), SDLoc(N));
-}]>;
-
-// We can commute a load in the first operand by swapping the sources and
-// rotating the immediate.
-let Predicates = [HasAVX, HasPCLMUL] in {
-  def : Pat<(int_x86_pclmulqdq (loadv2i64 addr:$src2), VR128:$src1,
-                                (i8 imm:$src3)),
-            (VPCLMULQDQrm VR128:$src1, addr:$src2,
-                          (PCLMULCommuteImm imm:$src3))>;
-}
-
-let Predicates = [NoAVX, HasPCLMUL] in {
-  def : Pat<(int_x86_pclmulqdq (loadv2i64 addr:$src2), VR128:$src1,
-                                (i8 imm:$src3)),
-            (PCLMULQDQrm VR128:$src1, addr:$src2,
-                          (PCLMULCommuteImm imm:$src3))>;
-}
-
 //===----------------------------------------------------------------------===//
 // SSE4A Instructions
 //===----------------------------------------------------------------------===//
index 84d9a914c9bbf7c4cc500059de28af5d513a9b49..1c2337cef2f7a5ae60b8dc6c3704b3a260b501de 100644 (file)
@@ -1,6 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+sse2,+pclmul | FileCheck %s --check-prefix=SSE
-; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx2,+pclmul | FileCheck %s --check-prefix=AVX
+; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown -mattr=+sse2,+pclmul | FileCheck %s --check-prefix=SSE
+; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown -mattr=+avx2,+pclmul | FileCheck %s --check-prefix=AVX
+; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown -mattr=+avx512vl,+vpclmulqdq | FileCheck %s --check-prefix=AVX
 
 declare <2 x i64> @llvm.x86.pclmulqdq(<2 x i64>, <2 x i64>, i8) nounwind readnone