[llvm] 86345eb - [X86] Add tests for `isKnownToBeAPowerOfTwo`; NFC

Noah Goldstein via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 15 23:59:27 PDT 2023


Author: Noah Goldstein
Date: 2023-08-16T02:00:14-05:00
New Revision: 86345eb45902d30d2ad5bbff8770ecb6ce2f7889

URL: https://github.com/llvm/llvm-project/commit/86345eb45902d30d2ad5bbff8770ecb6ce2f7889
DIFF: https://github.com/llvm/llvm-project/commit/86345eb45902d30d2ad5bbff8770ecb6ce2f7889.diff

LOG: [X86] Add tests for `isKnownToBeAPowerOfTwo`; NFC

Differential Revision: https://reviews.llvm.org/D156775

Added: 
    llvm/test/CodeGen/X86/known-pow2.ll

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/CodeGen/X86/known-pow2.ll b/llvm/test/CodeGen/X86/known-pow2.ll
new file mode 100644
index 00000000000000..579ed2d2495f82
--- /dev/null
+++ b/llvm/test/CodeGen/X86/known-pow2.ll
@@ -0,0 +1,867 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=CHECK
+
+; Use common transform of:
+; (X & Y) == Y -> (X & Y) != 0 iff Y is non-zero power of 2 to test.
+; (X & Y) != Y -> (X & Y) == 0 iff Y is non-zero power of 2 to test.
+
+declare i32 @llvm.umin.i32(i32, i32)
+declare i32 @llvm.umax.i32(i32, i32)
+declare i32 @llvm.smin.i32(i32, i32)
+declare i32 @llvm.smax.i32(i32, i32)
+declare i32 @llvm.fshl.i32(i32, i32, i32)
+declare i32 @llvm.fshr.i32(i32, i32, i32)
+
+define <4 x i32> @pow2_non_splat_vec(<4 x i32> %x) {
+; CHECK-LABEL: pow2_non_splat_vec:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-NEXT:    retq
+  %r = urem <4 x i32> %x, <i32 8, i32 4, i32 16, i32 64>
+  ret <4 x i32> %r
+}
+
+define <4 x i32> @pow2_non_splat_vec_fail0(<4 x i32> %x) {
+; CHECK-LABEL: pow2_non_splat_vec_fail0:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movdqa {{.*#+}} xmm1 = [954437177,1073741824,268435456,67108864]
+; CHECK-NEXT:    pmuludq %xmm0, %xmm1
+; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3]
+; CHECK-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[1,1,3,3]
+; CHECK-NEXT:    pmuludq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; CHECK-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[1,3,2,3]
+; CHECK-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
+; CHECK-NEXT:    movdqa %xmm1, %xmm3
+; CHECK-NEXT:    psrld $1, %xmm3
+; CHECK-NEXT:    shufps {{.*#+}} xmm3 = xmm3[0,1],xmm1[2,3]
+; CHECK-NEXT:    pmuludq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm3
+; CHECK-NEXT:    pshufd {{.*#+}} xmm1 = xmm3[0,2,2,3]
+; CHECK-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
+; CHECK-NEXT:    pmuludq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; CHECK-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
+; CHECK-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
+; CHECK-NEXT:    psubd %xmm1, %xmm0
+; CHECK-NEXT:    retq
+  %r = urem <4 x i32> %x, <i32 9, i32 4, i32 16, i32 64>
+  ret <4 x i32> %r
+}
+
+define i1 @pow2_shl(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_shl:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shrl %cl, %edi
+; CHECK-NEXT:    testb $4, %dil
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %d = shl nuw nsw i32 4, %y
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_shl_fail0(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_shl_fail0:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shrl %cl, %edi
+; CHECK-NEXT:    testb $3, %dil
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %d = shl i32 3, %y
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_shl_fail1(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_shl_fail1:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shrl %cl, %edi
+; CHECK-NEXT:    testb $4, %dil
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %d = shl i32 4, %y
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_srl(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_srl:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    andb $7, %cl
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %edi
+; CHECK-NEXT:    testl $1048576, %edi # imm = 0x100000
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = and i32 %y, 7
+  %d = lshr i32 1048576, %yy
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_srl_fail0(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_srl_fail0:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    andb $30, %cl
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %edi
+; CHECK-NEXT:    testl $1048576, %edi # imm = 0x100000
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = and i32 %y, 30
+  %d = lshr i32 1048576, %yy
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_srl_fail1(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_srl_fail1:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    andb $7, %cl
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %edi
+; CHECK-NEXT:    testl $1048577, %edi # imm = 0x100001
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = and i32 %y, 7
+  %d = lshr i32 1048577, %yy
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_rotl(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_rotl:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $1048576, %eax # imm = 0x100000
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    roll %cl, %eax
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %eax
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %d = call i32 @llvm.fshl.i32(i32 1048576, i32 1048576, i32 %y)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_rotl_fail0(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_rotl_fail0:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $1048576, %eax # imm = 0x100000
+; CHECK-NEXT:    movl $512, %edx # imm = 0x200
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shldl %cl, %eax, %edx
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %edx
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %d = call i32 @llvm.fshl.i32(i32 512, i32 1048576, i32 %y)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_rotl_fail1(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_rotl_fail1:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $511, %eax # imm = 0x1FF
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    roll %cl, %eax
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %eax
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %d = call i32 @llvm.fshl.i32(i32 511, i32 511, i32 %y)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_rotr(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_rotr:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $1048576, %eax # imm = 0x100000
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    rorl %cl, %eax
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %eax
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %d = call i32 @llvm.fshr.i32(i32 1048576, i32 1048576, i32 %y)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_rotr_fail0(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_rotr_fail0:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $512, %eax # imm = 0x200
+; CHECK-NEXT:    movl $1048576, %edx # imm = 0x100000
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shrdl %cl, %eax, %edx
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %edx
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %d = call i32 @llvm.fshr.i32(i32 512, i32 1048576, i32 %y)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_rotr_fail1(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_rotr_fail1:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $511, %eax # imm = 0x1FF
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    rorl %cl, %eax
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %eax
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %d = call i32 @llvm.fshr.i32(i32 511, i32 511, i32 %y)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_umin(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_umin:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    cmpl $262144, %eax # imm = 0x40000
+; CHECK-NEXT:    movl $262144, %ecx # imm = 0x40000
+; CHECK-NEXT:    cmovbl %eax, %ecx
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %ecx
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 1, %y
+  %d = call i32 @llvm.umin.i32(i32 %yy, i32 262144)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_umin_fail0(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_umin_fail0:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $4, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    cmpl $262144, %eax # imm = 0x40000
+; CHECK-NEXT:    movl $262144, %ecx # imm = 0x40000
+; CHECK-NEXT:    cmovbl %eax, %ecx
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %ecx
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 4, %y
+  %d = call i32 @llvm.umin.i32(i32 %yy, i32 262144)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_umin_fail1(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_umin_fail1:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    cmpl $12345, %eax # imm = 0x3039
+; CHECK-NEXT:    movl $12345, %ecx # imm = 0x3039
+; CHECK-NEXT:    cmovbl %eax, %ecx
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %ecx
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 1, %y
+  %d = call i32 @llvm.umin.i32(i32 %yy, i32 12345)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_umax(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: pow2_umax:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    movl $-2147483648, %esi # imm = 0x80000000
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    shrl %cl, %esi
+; CHECK-NEXT:    cmpl %esi, %eax
+; CHECK-NEXT:    cmoval %eax, %esi
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %esi
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 1, %y
+  %zz = lshr i32 2147483648, %z
+  %d = call i32 @llvm.umax.i32(i32 %yy, i32 %zz)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_umax_fail0(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: pow2_umax_fail0:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    movl $1073741824, %esi # imm = 0x40000000
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    shrl %cl, %esi
+; CHECK-NEXT:    cmpl %esi, %eax
+; CHECK-NEXT:    cmoval %eax, %esi
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %esi
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 1, %y
+  %zz = lshr i32 1073741824, %z
+  %d = call i32 @llvm.umax.i32(i32 %yy, i32 %zz)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_umax_fail1(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: pow2_umax_fail1:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $4, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    movl $-2147483648, %esi # imm = 0x80000000
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    shrl %cl, %esi
+; CHECK-NEXT:    cmpl %esi, %eax
+; CHECK-NEXT:    cmoval %eax, %esi
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %esi
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 4, %y
+  %zz = lshr i32 2147483648, %z
+  %d = call i32 @llvm.umax.i32(i32 %yy, i32 %zz)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_smin(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_smin:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    cmpl $262144, %eax # imm = 0x40000
+; CHECK-NEXT:    movl $262144, %ecx # imm = 0x40000
+; CHECK-NEXT:    cmovll %eax, %ecx
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %ecx
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 1, %y
+  %d = call i32 @llvm.smin.i32(i32 %yy, i32 262144)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_smin_fail0(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_smin_fail0:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $4, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    cmpl $262144, %eax # imm = 0x40000
+; CHECK-NEXT:    movl $262144, %ecx # imm = 0x40000
+; CHECK-NEXT:    cmovll %eax, %ecx
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %ecx
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 4, %y
+  %d = call i32 @llvm.smin.i32(i32 %yy, i32 262144)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_smin_fail1(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_smin_fail1:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    cmpl $12345, %eax # imm = 0x3039
+; CHECK-NEXT:    movl $12345, %ecx # imm = 0x3039
+; CHECK-NEXT:    cmovll %eax, %ecx
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %ecx
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 1, %y
+  %d = call i32 @llvm.smin.i32(i32 %yy, i32 12345)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_smax(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: pow2_smax:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    movl $-2147483648, %esi # imm = 0x80000000
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    shrl %cl, %esi
+; CHECK-NEXT:    cmpl %esi, %eax
+; CHECK-NEXT:    cmovgl %eax, %esi
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %esi
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 1, %y
+  %zz = lshr i32 2147483648, %z
+  %d = call i32 @llvm.smax.i32(i32 %yy, i32 %zz)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_smax_fail0(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: pow2_smax_fail0:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    movl $1073741824, %esi # imm = 0x40000000
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    shrl %cl, %esi
+; CHECK-NEXT:    cmpl %esi, %eax
+; CHECK-NEXT:    cmovgl %eax, %esi
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %esi
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 1, %y
+  %zz = lshr i32 1073741824, %z
+  %d = call i32 @llvm.smax.i32(i32 %yy, i32 %zz)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_smax_fail1(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: pow2_smax_fail1:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $4, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    movl $-2147483648, %esi # imm = 0x80000000
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    shrl %cl, %esi
+; CHECK-NEXT:    cmpl %esi, %eax
+; CHECK-NEXT:    cmovgl %eax, %esi
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %esi
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 4, %y
+  %zz = lshr i32 2147483648, %z
+  %d = call i32 @llvm.smax.i32(i32 %yy, i32 %zz)
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_select(i1 %c, i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: pow2_select:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %ecx, %eax
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    movl $1, %edx
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %edx
+; CHECK-NEXT:    movl $-2147483648, %r8d # imm = 0x80000000
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %r8d
+; CHECK-NEXT:    testb $1, %dil
+; CHECK-NEXT:    cmovnel %edx, %r8d
+; CHECK-NEXT:    notl %esi
+; CHECK-NEXT:    testl %esi, %r8d
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 1, %y
+  %zz = lshr i32 2147483648, %z
+  %d = select i1 %c, i32 %yy, i32 %zz
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_select_fail0(i1 %c, i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: pow2_select_fail0:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %ecx, %eax
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    movl $1, %edx
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %edx
+; CHECK-NEXT:    movl $1073741824, %r8d # imm = 0x40000000
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %r8d
+; CHECK-NEXT:    testb $1, %dil
+; CHECK-NEXT:    cmovnel %edx, %r8d
+; CHECK-NEXT:    notl %esi
+; CHECK-NEXT:    testl %esi, %r8d
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 1, %y
+  %zz = lshr i32 1073741824, %z
+  %d = select i1 %c, i32 %yy, i32 %zz
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_select_fail2(i1 %c, i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: pow2_select_fail2:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %ecx, %eax
+; CHECK-NEXT:    movl %edx, %ecx
+; CHECK-NEXT:    movl $4, %edx
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %edx
+; CHECK-NEXT:    movl $-2147483648, %r8d # imm = 0x80000000
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    shrl %cl, %r8d
+; CHECK-NEXT:    testb $1, %dil
+; CHECK-NEXT:    cmovnel %edx, %r8d
+; CHECK-NEXT:    notl %esi
+; CHECK-NEXT:    testl %esi, %r8d
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 4, %y
+  %zz = lshr i32 2147483648, %z
+  %d = select i1 %c, i32 %yy, i32 %zz
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define <4 x i1> @pow2_vselect_eq(<4 x i1> %c, <4 x i32> %x, <4 x i32> %y, <4 x i32> %z) {
+; CHECK-LABEL: pow2_vselect_eq:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pslld $31, %xmm0
+; CHECK-NEXT:    psrad $31, %xmm0
+; CHECK-NEXT:    pslld $23, %xmm2
+; CHECK-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; CHECK-NEXT:    cvttps2dq %xmm2, %xmm2
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm4 = xmm3[2,3,3,3,4,5,6,7]
+; CHECK-NEXT:    movdqa {{.*#+}} xmm5 = [2147483648,2147483648,2147483648,2147483648]
+; CHECK-NEXT:    movdqa %xmm5, %xmm6
+; CHECK-NEXT:    psrld %xmm4, %xmm6
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm4 = xmm3[0,1,1,1,4,5,6,7]
+; CHECK-NEXT:    movdqa %xmm5, %xmm7
+; CHECK-NEXT:    psrld %xmm4, %xmm7
+; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm7 = xmm7[0],xmm6[0]
+; CHECK-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[2,3,2,3]
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm4 = xmm3[2,3,3,3,4,5,6,7]
+; CHECK-NEXT:    movdqa %xmm5, %xmm6
+; CHECK-NEXT:    psrld %xmm4, %xmm6
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm3 = xmm3[0,1,1,1,4,5,6,7]
+; CHECK-NEXT:    psrld %xmm3, %xmm5
+; CHECK-NEXT:    punpckhqdq {{.*#+}} xmm5 = xmm5[1],xmm6[1]
+; CHECK-NEXT:    shufps {{.*#+}} xmm7 = xmm7[0,3],xmm5[0,3]
+; CHECK-NEXT:    pand %xmm0, %xmm2
+; CHECK-NEXT:    pandn %xmm7, %xmm0
+; CHECK-NEXT:    por %xmm2, %xmm0
+; CHECK-NEXT:    pand %xmm0, %xmm1
+; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
+; CHECK-NEXT:    retq
+  %yy = shl <4 x i32> <i32 1, i32 1, i32 1, i32 1>, %y
+  %zz = lshr <4 x i32> <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147483648>, %z
+  %d = select <4 x i1> %c, <4 x i32> %yy, <4 x i32> %zz
+  %and = and <4 x i32> %x, %d
+  %r = icmp eq <4 x i32> %and, %d
+  ret <4 x i1> %r
+}
+
+define <4 x i1> @pow2_vselect_ne(<4 x i1> %c, <4 x i32> %x, <4 x i32> %y, <4 x i32> %z) {
+; CHECK-LABEL: pow2_vselect_ne:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pslld $31, %xmm0
+; CHECK-NEXT:    psrad $31, %xmm0
+; CHECK-NEXT:    pslld $23, %xmm2
+; CHECK-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; CHECK-NEXT:    cvttps2dq %xmm2, %xmm2
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm4 = xmm3[2,3,3,3,4,5,6,7]
+; CHECK-NEXT:    movdqa {{.*#+}} xmm5 = [2147483648,2147483648,2147483648,2147483648]
+; CHECK-NEXT:    movdqa %xmm5, %xmm6
+; CHECK-NEXT:    psrld %xmm4, %xmm6
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm4 = xmm3[0,1,1,1,4,5,6,7]
+; CHECK-NEXT:    movdqa %xmm5, %xmm7
+; CHECK-NEXT:    psrld %xmm4, %xmm7
+; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm7 = xmm7[0],xmm6[0]
+; CHECK-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[2,3,2,3]
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm4 = xmm3[2,3,3,3,4,5,6,7]
+; CHECK-NEXT:    movdqa %xmm5, %xmm6
+; CHECK-NEXT:    psrld %xmm4, %xmm6
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm3 = xmm3[0,1,1,1,4,5,6,7]
+; CHECK-NEXT:    psrld %xmm3, %xmm5
+; CHECK-NEXT:    punpckhqdq {{.*#+}} xmm5 = xmm5[1],xmm6[1]
+; CHECK-NEXT:    shufps {{.*#+}} xmm7 = xmm7[0,3],xmm5[0,3]
+; CHECK-NEXT:    pand %xmm0, %xmm2
+; CHECK-NEXT:    pandn %xmm7, %xmm0
+; CHECK-NEXT:    por %xmm2, %xmm0
+; CHECK-NEXT:    pcmpeqd %xmm2, %xmm2
+; CHECK-NEXT:    pand %xmm0, %xmm1
+; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
+; CHECK-NEXT:    pxor %xmm2, %xmm0
+; CHECK-NEXT:    retq
+  %yy = shl <4 x i32> <i32 1, i32 1, i32 1, i32 1>, %y
+  %zz = lshr <4 x i32> <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147483648>, %z
+  %d = select <4 x i1> %c, <4 x i32> %yy, <4 x i32> %zz
+  %and = and <4 x i32> %x, %d
+  %r = icmp ne <4 x i32> %and, %d
+  ret <4 x i1> %r
+}
+
+define <4 x i1> @pow2_vselect_fail0_ne(<4 x i1> %c, <4 x i32> %x, <4 x i32> %y, <4 x i32> %z) {
+; CHECK-LABEL: pow2_vselect_fail0_ne:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pslld $31, %xmm0
+; CHECK-NEXT:    psrad $31, %xmm0
+; CHECK-NEXT:    pslld $23, %xmm2
+; CHECK-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; CHECK-NEXT:    cvttps2dq %xmm2, %xmm2
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm4 = xmm3[2,3,3,3,4,5,6,7]
+; CHECK-NEXT:    movdqa {{.*#+}} xmm5 = [1073741824,1073741824,1073741824,1073741824]
+; CHECK-NEXT:    movdqa %xmm5, %xmm6
+; CHECK-NEXT:    psrld %xmm4, %xmm6
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm4 = xmm3[0,1,1,1,4,5,6,7]
+; CHECK-NEXT:    movdqa %xmm5, %xmm7
+; CHECK-NEXT:    psrld %xmm4, %xmm7
+; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm7 = xmm7[0],xmm6[0]
+; CHECK-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[2,3,2,3]
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm4 = xmm3[2,3,3,3,4,5,6,7]
+; CHECK-NEXT:    movdqa %xmm5, %xmm6
+; CHECK-NEXT:    psrld %xmm4, %xmm6
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm3 = xmm3[0,1,1,1,4,5,6,7]
+; CHECK-NEXT:    psrld %xmm3, %xmm5
+; CHECK-NEXT:    punpckhqdq {{.*#+}} xmm5 = xmm5[1],xmm6[1]
+; CHECK-NEXT:    shufps {{.*#+}} xmm7 = xmm7[0,3],xmm5[0,3]
+; CHECK-NEXT:    pand %xmm0, %xmm2
+; CHECK-NEXT:    pandn %xmm7, %xmm0
+; CHECK-NEXT:    por %xmm2, %xmm0
+; CHECK-NEXT:    pcmpeqd %xmm2, %xmm2
+; CHECK-NEXT:    pand %xmm0, %xmm1
+; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
+; CHECK-NEXT:    pxor %xmm2, %xmm0
+; CHECK-NEXT:    retq
+  %yy = shl <4 x i32> <i32 1, i32 1, i32 1, i32 1>, %y
+  %zz = lshr <4 x i32> <i32 1073741824, i32 1073741824, i32 1073741824, i32 1073741824>, %z
+  %d = select <4 x i1> %c, <4 x i32> %yy, <4 x i32> %zz
+  %and = and <4 x i32> %x, %d
+  %r = icmp ne <4 x i32> %and, %d
+  ret <4 x i1> %r
+}
+
+define <4 x i1> @pow2_vselect_fail2_ne(<4 x i1> %c, <4 x i32> %x, <4 x i32> %y, <4 x i32> %z) {
+; CHECK-LABEL: pow2_vselect_fail2_ne:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pslld $31, %xmm0
+; CHECK-NEXT:    psrad $31, %xmm0
+; CHECK-NEXT:    pslld $23, %xmm2
+; CHECK-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; CHECK-NEXT:    cvttps2dq %xmm2, %xmm2
+; CHECK-NEXT:    movdqa {{.*#+}} xmm4 = [4,4,4,4]
+; CHECK-NEXT:    pshufd {{.*#+}} xmm5 = xmm2[1,1,3,3]
+; CHECK-NEXT:    pmuludq %xmm4, %xmm2
+; CHECK-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
+; CHECK-NEXT:    pmuludq %xmm4, %xmm5
+; CHECK-NEXT:    pshufd {{.*#+}} xmm4 = xmm5[0,2,2,3]
+; CHECK-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1]
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm4 = xmm3[2,3,3,3,4,5,6,7]
+; CHECK-NEXT:    movdqa {{.*#+}} xmm5 = [2147483648,2147483648,2147483648,2147483648]
+; CHECK-NEXT:    movdqa %xmm5, %xmm6
+; CHECK-NEXT:    psrld %xmm4, %xmm6
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm4 = xmm3[0,1,1,1,4,5,6,7]
+; CHECK-NEXT:    movdqa %xmm5, %xmm7
+; CHECK-NEXT:    psrld %xmm4, %xmm7
+; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm7 = xmm7[0],xmm6[0]
+; CHECK-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[2,3,2,3]
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm4 = xmm3[2,3,3,3,4,5,6,7]
+; CHECK-NEXT:    movdqa %xmm5, %xmm6
+; CHECK-NEXT:    psrld %xmm4, %xmm6
+; CHECK-NEXT:    pshuflw {{.*#+}} xmm3 = xmm3[0,1,1,1,4,5,6,7]
+; CHECK-NEXT:    psrld %xmm3, %xmm5
+; CHECK-NEXT:    punpckhqdq {{.*#+}} xmm5 = xmm5[1],xmm6[1]
+; CHECK-NEXT:    shufps {{.*#+}} xmm7 = xmm7[0,3],xmm5[0,3]
+; CHECK-NEXT:    pand %xmm0, %xmm2
+; CHECK-NEXT:    pandn %xmm7, %xmm0
+; CHECK-NEXT:    por %xmm2, %xmm0
+; CHECK-NEXT:    pcmpeqd %xmm2, %xmm2
+; CHECK-NEXT:    pand %xmm0, %xmm1
+; CHECK-NEXT:    pcmpeqd %xmm1, %xmm0
+; CHECK-NEXT:    pxor %xmm2, %xmm0
+; CHECK-NEXT:    retq
+  %yy = shl <4 x i32> <i32 4, i32 4, i32 4, i32 4>, %y
+  %zz = lshr <4 x i32> <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147483648>, %z
+  %d = select <4 x i1> %c, <4 x i32> %yy, <4 x i32> %zz
+  %and = and <4 x i32> %x, %d
+  %r = icmp ne <4 x i32> %and, %d
+  ret <4 x i1> %r
+}
+
+define i1 @pow2_and(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_and:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $4, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    negl %ecx
+; CHECK-NEXT:    andl %eax, %ecx
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %ecx
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl nuw nsw i32 4, %y
+  %nyy = sub i32 0, %yy
+  %d = and i32 %yy, %nyy
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_and_fail0(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_and_fail0:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $4, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    movl %eax, %ecx
+; CHECK-NEXT:    negl %ecx
+; CHECK-NEXT:    andl %eax, %ecx
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %ecx
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 4, %y
+  %nyy = sub i32 0, %yy
+  %d = and i32 %yy, %nyy
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_and_fail1(i32 %x, i32 %y) {
+; CHECK-LABEL: pow2_and_fail1:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    movl $1, %edx
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %edx
+; CHECK-NEXT:    subl %edx, %eax
+; CHECK-NEXT:    andl %edx, %eax
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %eax
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 1, %y
+  %nyy = sub i32 1, %yy
+  %d = and i32 %yy, %nyy
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_and_fail2(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: pow2_and_fail2:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    andl %edx, %eax
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    testl %edi, %eax
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %yy = shl i32 1, %y
+  %d = and i32 %yy, %z
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}
+
+define i1 @pow2_though_zext(i32 %x, i16 %y) {
+; CHECK-LABEL: pow2_though_zext:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl %esi, %ecx
+; CHECK-NEXT:    movl $4, %eax
+; CHECK-NEXT:    # kill: def $cl killed $cl killed $ecx
+; CHECK-NEXT:    shll %cl, %eax
+; CHECK-NEXT:    notl %edi
+; CHECK-NEXT:    andl %eax, %edi
+; CHECK-NEXT:    testl $65535, %edi # imm = 0xFFFF
+; CHECK-NEXT:    sete %al
+; CHECK-NEXT:    retq
+  %dd = shl nuw nsw i16 4, %y
+  %d = zext i16 %dd to i32
+  %and = and i32 %x, %d
+  %r = icmp eq i32 %and, %d
+  ret i1 %r
+}


        


More information about the llvm-commits mailing list