summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2016-08-01 12:11:43 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2016-08-01 12:11:43 +0000
commit46f119a59f2cc4b38a9a5be01bf33e684df20866 (patch)
tree4271b2aa07097e8305e67d90fbdda4ea1be52abb
parent11cea45ccef4e7878f60b2c296569362a2b26b97 (diff)
downloadbcm5719-llvm-46f119a59f2cc4b38a9a5be01bf33e684df20866.tar.gz
bcm5719-llvm-46f119a59f2cc4b38a9a5be01bf33e684df20866.zip
[X86] Use implicit masking of SHLD/SHRD shift double instructions
Similar to the regular shift instructions, SHLD/SHRD only use the bottom bits of the shift value llvm-svn: 277341
-rw-r--r--llvm/lib/Target/X86/X86InstrCompiler.td19
-rw-r--r--llvm/test/CodeGen/X86/shift-double.ll17
2 files changed, 20 insertions, 16 deletions
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td
index 4c85b232f1d..4264b5b5023 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -1709,6 +1709,22 @@ defm : MaskedShiftAmountPats<sra, "SAR">;
defm : MaskedShiftAmountPats<rotl, "ROL">;
defm : MaskedShiftAmountPats<rotr, "ROR">;
+// Double shift amount is implicitly masked.
+multiclass MaskedDoubleShiftAmountPats<SDNode frag, string name> {
+ // (shift x (and y, 31)) ==> (shift x, y)
+ def : Pat<(frag GR16:$src1, GR16:$src2, (and CL, immShift32)),
+ (!cast<Instruction>(name # "16rrCL") GR16:$src1, GR16:$src2)>;
+ def : Pat<(frag GR32:$src1, GR32:$src2, (and CL, immShift32)),
+ (!cast<Instruction>(name # "32rrCL") GR32:$src1, GR32:$src2)>;
+
+ // (shift x (and y, 63)) ==> (shift x, y)
+ def : Pat<(frag GR64:$src1, GR64:$src2, (and CL, immShift64)),
+ (!cast<Instruction>(name # "64rrCL") GR64:$src1, GR64:$src2)>;
+}
+
+defm : MaskedDoubleShiftAmountPats<X86shld, "SHLD">;
+defm : MaskedDoubleShiftAmountPats<X86shrd, "SHRD">;
+
// (anyext (setcc_carry)) -> (setcc_carry)
def : Pat<(i16 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
(SETB_C16r)>;
@@ -1717,9 +1733,6 @@ def : Pat<(i32 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
def : Pat<(i32 (anyext (i16 (X86setcc_c X86_COND_B, EFLAGS)))),
(SETB_C32r)>;
-
-
-
//===----------------------------------------------------------------------===//
// EFLAGS-defining Patterns
//===----------------------------------------------------------------------===//
diff --git a/llvm/test/CodeGen/X86/shift-double.ll b/llvm/test/CodeGen/X86/shift-double.ll
index ba9baea9862..8594c071329 100644
--- a/llvm/test/CodeGen/X86/shift-double.ll
+++ b/llvm/test/CodeGen/X86/shift-double.ll
@@ -156,7 +156,6 @@ define i64 @test8(i64 %val, i32 %bits) nounwind {
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: shll %cl, %eax
-; CHECK-NEXT: andb $31, %cl
; CHECK-NEXT: shldl %cl, %esi, %edx
; CHECK-NEXT: popl %esi
; CHECK-NEXT: retl
@@ -169,15 +168,11 @@ define i64 @test8(i64 %val, i32 %bits) nounwind {
define i64 @test9(i64 %val, i32 %bits) nounwind {
; CHECK-LABEL: test9:
; CHECK: # BB#0:
-; CHECK-NEXT: pushl %esi
; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
-; CHECK-NEXT: movl {{[0-9]+}}(%esp), %esi
-; CHECK-NEXT: movl %esi, %edx
+; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx
+; CHECK-NEXT: shrdl %cl, %edx, %eax
; CHECK-NEXT: sarl %cl, %edx
-; CHECK-NEXT: andb $31, %cl
-; CHECK-NEXT: shrdl %cl, %esi, %eax
-; CHECK-NEXT: popl %esi
; CHECK-NEXT: retl
%and = and i32 %bits, 31
%sh_prom = zext i32 %and to i64
@@ -188,15 +183,11 @@ define i64 @test9(i64 %val, i32 %bits) nounwind {
define i64 @test10(i64 %val, i32 %bits) nounwind {
; CHECK-LABEL: test10:
; CHECK: # BB#0:
-; CHECK-NEXT: pushl %esi
; CHECK-NEXT: movb {{[0-9]+}}(%esp), %cl
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
-; CHECK-NEXT: movl {{[0-9]+}}(%esp), %esi
-; CHECK-NEXT: movl %esi, %edx
+; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx
+; CHECK-NEXT: shrdl %cl, %edx, %eax
; CHECK-NEXT: shrl %cl, %edx
-; CHECK-NEXT: andb $31, %cl
-; CHECK-NEXT: shrdl %cl, %esi, %eax
-; CHECK-NEXT: popl %esi
; CHECK-NEXT: retl
%and = and i32 %bits, 31
%sh_prom = zext i32 %and to i64
OpenPOWER on IntegriCloud