From f893d49f0ceddb804af589de33f20e010402ffbd Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 9 May 2017 16:32:11 +0000 Subject: [X86] Add more patterns for BZHI isel This patch adds more patterns that a reasonable person might write that can be compiled to BZHI. This adds support for (~0U >> (32 - b)) & a; and a << (32 - b) >> (32 - b); This was inspired by the code in APInt::clearUnusedBits. This can pass an index of 32 to the bzhi instruction which a quick test of Haswell hardware shows will not mask any bits. Though the description text in the Intel manual says the "index is saturated to OperandSize-1". The pseudocode in the same manual indicates no bits will be zeroed for this case. I think this is still missing cases where the subtract portion is an 8-bit operation. Differential Revision: https://reviews.llvm.org/D32616 llvm-svn: 302549 --- llvm/test/CodeGen/X86/bmi.ll | 76 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) (limited to 'llvm/test/CodeGen/X86/bmi.ll') diff --git a/llvm/test/CodeGen/X86/bmi.ll b/llvm/test/CodeGen/X86/bmi.ll index afeba4ef2d9..94e2ee7a0aa 100644 --- a/llvm/test/CodeGen/X86/bmi.ll +++ b/llvm/test/CodeGen/X86/bmi.ll @@ -454,6 +454,30 @@ entry: ret i32 %and } +define i32 @bzhi32d(i32 %a, i32 %b) { +; CHECK-LABEL: bzhi32d: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: bzhil %esi, %edi, %eax +; CHECK-NEXT: retq +entry: + %sub = sub i32 32, %b + %shr = lshr i32 -1, %sub + %and = and i32 %shr, %a + ret i32 %and +} + +define i32 @bzhi32e(i32 %a, i32 %b) { +; CHECK-LABEL: bzhi32e: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: bzhil %esi, %edi, %eax +; CHECK-NEXT: retq +entry: + %sub = sub i32 32, %b + %shl = shl i32 %a, %sub + %shr = lshr i32 %shl, %sub + ret i32 %shr +} + define i64 @bzhi64b(i64 %x, i8 zeroext %index) { ; CHECK-LABEL: bzhi64b: ; CHECK: # BB#0: # %entry @@ -468,6 +492,58 @@ entry: ret i64 %and } +define i64 @bzhi64c(i64 %a, i64 %b) { +; CHECK-LABEL: bzhi64c: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: bzhiq %rsi, %rdi, %rax +; CHECK-NEXT: retq +entry: + %sub = sub i64 64, %b + %shr = lshr i64 -1, %sub + %and = and i64 %shr, %a + ret i64 %and +} + +define i64 @bzhi64d(i64 %a, i32 %b) { +; CHECK-LABEL: bzhi64d: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: # kill: %ESI %ESI %RSI +; CHECK-NEXT: bzhiq %rsi, %rdi, %rax +; CHECK-NEXT: retq +entry: + %sub = sub i32 64, %b + %sh_prom = zext i32 %sub to i64 + %shr = lshr i64 -1, %sh_prom + %and = and i64 %shr, %a + ret i64 %and +} + +define i64 @bzhi64e(i64 %a, i64 %b) { +; CHECK-LABEL: bzhi64e: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: bzhiq %rsi, %rdi, %rax +; CHECK-NEXT: retq +entry: + %sub = sub i64 64, %b + %shl = shl i64 %a, %sub + %shr = lshr i64 %shl, %sub + ret i64 %shr +} + +define i64 @bzhi64f(i64 %a, i32 %b) { +; CHECK-LABEL: bzhi64f: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: # kill: %ESI %ESI %RSI +; CHECK-NEXT: bzhiq %rsi, %rdi, %rax +; CHECK-NEXT: retq +entry: + %sub = sub i32 64, %b + %sh_prom = zext i32 %sub to i64 + %shl = shl i64 %a, %sh_prom + %shr = lshr i64 %shl, %sh_prom + ret i64 %shr +} + define i64 @bzhi64_constant_mask(i64 %x) { ; CHECK-LABEL: bzhi64_constant_mask: ; CHECK: # BB#0: # %entry -- cgit v1.2.3