[llvm] r337014 - [NFC][X86][AArch64] Negative tests for 'check for [no] signed truncation' pattern

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 13 09:14:37 PDT 2018


Author: lebedevri
Date: Fri Jul 13 09:14:37 2018
New Revision: 337014

URL: http://llvm.org/viewvc/llvm-project?rev=337014&view=rev
Log:
[NFC][X86][AArch64] Negative tests for 'check for [no] signed truncation' pattern

See D49247, D49266

I'm only adding the sane negative tests, and not
adding the one-use tests yet. Also, not adding
negative tests for the second pattern with inverted operands yet,
since it's handling will be added in later differential.

Modified:
    llvm/trunk/test/CodeGen/AArch64/lack-of-signed-truncation-check.ll
    llvm/trunk/test/CodeGen/AArch64/signed-truncation-check.ll
    llvm/trunk/test/CodeGen/X86/lack-of-signed-truncation-check.ll
    llvm/trunk/test/CodeGen/X86/signed-truncation-check.ll

Modified: llvm/trunk/test/CodeGen/AArch64/lack-of-signed-truncation-check.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/lack-of-signed-truncation-check.ll?rev=337014&r1=337013&r2=337014&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/lack-of-signed-truncation-check.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/lack-of-signed-truncation-check.ll Fri Jul 13 09:14:37 2018
@@ -256,3 +256,118 @@ define i1 @add_ugecmp_i64_i8(i64 %x) nou
   %tmp1 = icmp uge i64 %tmp0, 256 ; 1U << 8
   ret i1 %tmp1
 }
+
+; Negative tests
+; ---------------------------------------------------------------------------- ;
+
+; Adding not a constant
+define i1 @add_ugecmp_bad_i16_i8_add(i16 %x, i16 %y) nounwind {
+; CHECK-LABEL: add_ugecmp_bad_i16_i8_add:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, w1
+; CHECK-NEXT:    and w8, w8, #0xffff
+; CHECK-NEXT:    cmp w8, #255 // =255
+; CHECK-NEXT:    cset w0, hi
+; CHECK-NEXT:    ret
+  %tmp0 = add i16 %x, %y
+  %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}
+
+; Comparing not with a constant
+define i1 @add_ugecmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind {
+; CHECK-LABEL: add_ugecmp_bad_i16_i8_cmp:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, #128 // =128
+; CHECK-NEXT:    and w8, w8, #0xffff
+; CHECK-NEXT:    cmp w8, w1, uxth
+; CHECK-NEXT:    cset w0, hs
+; CHECK-NEXT:    ret
+  %tmp0 = add i16 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp uge i16 %tmp0, %y
+  ret i1 %tmp1
+}
+
+; Second constant is not larger than the first one
+define i1 @add_ugecmp_bad_i8_i16(i16 %x) nounwind {
+; CHECK-LABEL: add_ugecmp_bad_i8_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, #128 // =128
+; CHECK-NEXT:    and w8, w8, #0xffff
+; CHECK-NEXT:    cmp w8, #127 // =127
+; CHECK-NEXT:    cset w0, hi
+; CHECK-NEXT:    ret
+  %tmp0 = add i16 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp uge i16 %tmp0, 128 ; 1U << (8-1)
+  ret i1 %tmp1
+}
+
+; First constant is not power of two
+define i1 @add_ugecmp_bad_i16_i8_c0notpoweroftwo(i16 %x) nounwind {
+; CHECK-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, #192 // =192
+; CHECK-NEXT:    and w8, w8, #0xffff
+; CHECK-NEXT:    cmp w8, #255 // =255
+; CHECK-NEXT:    cset w0, hi
+; CHECK-NEXT:    ret
+  %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1))
+  %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}
+
+; Second constant is not power of two
+define i1 @add_ugecmp_bad_i16_i8_c1notpoweroftwo(i16 %x) nounwind {
+; CHECK-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, #128 // =128
+; CHECK-NEXT:    and w8, w8, #0xffff
+; CHECK-NEXT:    cmp w8, #767 // =767
+; CHECK-NEXT:    cset w0, hi
+; CHECK-NEXT:    ret
+  %tmp0 = add i16 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp uge i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1))
+  ret i1 %tmp1
+}
+
+; Magic check fails, 64 << 1 != 256
+define i1 @add_ugecmp_bad_i16_i8_magic(i16 %x) nounwind {
+; CHECK-LABEL: add_ugecmp_bad_i16_i8_magic:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, #64 // =64
+; CHECK-NEXT:    and w8, w8, #0xffff
+; CHECK-NEXT:    cmp w8, #255 // =255
+; CHECK-NEXT:    cset w0, hi
+; CHECK-NEXT:    ret
+  %tmp0 = add i16 %x, 64 ; 1U << (8-1-1)
+  %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}
+
+; Bad 'destination type'
+define i1 @add_ugecmp_bad_i16_i4(i16 %x) nounwind {
+; CHECK-LABEL: add_ugecmp_bad_i16_i4:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, #8 // =8
+; CHECK-NEXT:    and w8, w8, #0xffff
+; CHECK-NEXT:    cmp w8, #15 // =15
+; CHECK-NEXT:    cset w0, hi
+; CHECK-NEXT:    ret
+  %tmp0 = add i16 %x, 8 ; 1U << (4-1)
+  %tmp1 = icmp uge i16 %tmp0, 16 ; 1U << 4
+  ret i1 %tmp1
+}
+
+; Bad storage type
+define i1 @add_ugecmp_bad_i24_i8(i24 %x) nounwind {
+; CHECK-LABEL: add_ugecmp_bad_i24_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, #128 // =128
+; CHECK-NEXT:    and w8, w8, #0xffffff
+; CHECK-NEXT:    cmp w8, #255 // =255
+; CHECK-NEXT:    cset w0, hi
+; CHECK-NEXT:    ret
+  %tmp0 = add i24 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp uge i24 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}

Modified: llvm/trunk/test/CodeGen/AArch64/signed-truncation-check.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/signed-truncation-check.ll?rev=337014&r1=337013&r2=337014&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/signed-truncation-check.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/signed-truncation-check.ll Fri Jul 13 09:14:37 2018
@@ -256,3 +256,117 @@ define i1 @add_ultcmp_i64_i8(i64 %x) nou
   %tmp1 = icmp ult i64 %tmp0, 256 ; 1U << 8
   ret i1 %tmp1
 }
+
+; Negative tests
+; ---------------------------------------------------------------------------- ;
+
+; Adding not a constant
+define i1 @add_ultcmp_bad_i16_i8_add(i16 %x, i16 %y) nounwind {
+; CHECK-LABEL: add_ultcmp_bad_i16_i8_add:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, w1
+; CHECK-NEXT:    and w8, w8, #0xffff
+; CHECK-NEXT:    cmp w8, #256 // =256
+; CHECK-NEXT:    cset w0, lo
+; CHECK-NEXT:    ret
+  %tmp0 = add i16 %x, %y
+  %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}
+
+; Comparing not with a constant
+define i1 @add_ultcmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind {
+; CHECK-LABEL: add_ultcmp_bad_i16_i8_cmp:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, #128 // =128
+; CHECK-NEXT:    and w8, w8, #0xffff
+; CHECK-NEXT:    cmp w8, w1, uxth
+; CHECK-NEXT:    cset w0, lo
+; CHECK-NEXT:    ret
+  %tmp0 = add i16 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp ult i16 %tmp0, %y
+  ret i1 %tmp1
+}
+
+; Second constant is not larger than the first one
+define i1 @add_ultcmp_bad_i8_i16(i16 %x) nounwind {
+; CHECK-LABEL: add_ultcmp_bad_i8_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    and w8, w0, #0xffff
+; CHECK-NEXT:    add w8, w8, #128 // =128
+; CHECK-NEXT:    lsr w0, w8, #16
+; CHECK-NEXT:    ret
+  %tmp0 = add i16 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp ult i16 %tmp0, 128 ; 1U << (8-1)
+  ret i1 %tmp1
+}
+
+; First constant is not power of two
+define i1 @add_ultcmp_bad_i16_i8_c0notpoweroftwo(i16 %x) nounwind {
+; CHECK-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, #192 // =192
+; CHECK-NEXT:    and w8, w8, #0xffff
+; CHECK-NEXT:    cmp w8, #256 // =256
+; CHECK-NEXT:    cset w0, lo
+; CHECK-NEXT:    ret
+  %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1))
+  %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}
+
+; Second constant is not power of two
+define i1 @add_ultcmp_bad_i16_i8_c1notpoweroftwo(i16 %x) nounwind {
+; CHECK-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, #128 // =128
+; CHECK-NEXT:    and w8, w8, #0xffff
+; CHECK-NEXT:    cmp w8, #768 // =768
+; CHECK-NEXT:    cset w0, lo
+; CHECK-NEXT:    ret
+  %tmp0 = add i16 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp ult i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1))
+  ret i1 %tmp1
+}
+
+; Magic check fails, 64 << 1 != 256
+define i1 @add_ultcmp_bad_i16_i8_magic(i16 %x) nounwind {
+; CHECK-LABEL: add_ultcmp_bad_i16_i8_magic:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, #64 // =64
+; CHECK-NEXT:    and w8, w8, #0xffff
+; CHECK-NEXT:    cmp w8, #256 // =256
+; CHECK-NEXT:    cset w0, lo
+; CHECK-NEXT:    ret
+  %tmp0 = add i16 %x, 64 ; 1U << (8-1-1)
+  %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}
+
+; Bad 'destination type'
+define i1 @add_ultcmp_bad_i16_i4(i16 %x) nounwind {
+; CHECK-LABEL: add_ultcmp_bad_i16_i4:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, #8 // =8
+; CHECK-NEXT:    and w8, w8, #0xffff
+; CHECK-NEXT:    cmp w8, #16 // =16
+; CHECK-NEXT:    cset w0, lo
+; CHECK-NEXT:    ret
+  %tmp0 = add i16 %x, 8 ; 1U << (4-1)
+  %tmp1 = icmp ult i16 %tmp0, 16 ; 1U << 4
+  ret i1 %tmp1
+}
+
+; Bad storage type
+define i1 @add_ultcmp_bad_i24_i8(i24 %x) nounwind {
+; CHECK-LABEL: add_ultcmp_bad_i24_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add w8, w0, #128 // =128
+; CHECK-NEXT:    and w8, w8, #0xffffff
+; CHECK-NEXT:    cmp w8, #256 // =256
+; CHECK-NEXT:    cset w0, lo
+; CHECK-NEXT:    ret
+  %tmp0 = add i24 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp ult i24 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}

Modified: llvm/trunk/test/CodeGen/X86/lack-of-signed-truncation-check.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/lack-of-signed-truncation-check.ll?rev=337014&r1=337013&r2=337014&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/lack-of-signed-truncation-check.ll (original)
+++ llvm/trunk/test/CodeGen/X86/lack-of-signed-truncation-check.ll Fri Jul 13 09:14:37 2018
@@ -428,3 +428,188 @@ define i1 @add_ugecmp_i64_i8(i64 %x) nou
   %tmp1 = icmp uge i64 %tmp0, 256 ; 1U << 8
   ret i1 %tmp1
 }
+
+; Negative tests
+; ---------------------------------------------------------------------------- ;
+
+; Adding not a constant
+define i1 @add_ugecmp_bad_i16_i8_add(i16 %x, i16 %y) nounwind {
+; X86-LABEL: add_ugecmp_bad_i16_i8_add:
+; X86:       # %bb.0:
+; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    addw {{[0-9]+}}(%esp), %ax
+; X86-NEXT:    movzwl %ax, %eax
+; X86-NEXT:    cmpl $255, %eax
+; X86-NEXT:    seta %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ugecmp_bad_i16_i8_add:
+; X64:       # %bb.0:
+; X64-NEXT:    addl %esi, %edi
+; X64-NEXT:    movzwl %di, %eax
+; X64-NEXT:    cmpl $255, %eax
+; X64-NEXT:    seta %al
+; X64-NEXT:    retq
+  %tmp0 = add i16 %x, %y
+  %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}
+
+; Comparing not with a constant
+define i1 @add_ugecmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind {
+; X86-LABEL: add_ugecmp_bad_i16_i8_cmp:
+; X86:       # %bb.0:
+; X86-NEXT:    movl $128, %eax
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    cmpw {{[0-9]+}}(%esp), %ax
+; X86-NEXT:    setae %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ugecmp_bad_i16_i8_cmp:
+; X64:       # %bb.0:
+; X64-NEXT:    subl $-128, %edi
+; X64-NEXT:    cmpw %si, %di
+; X64-NEXT:    setae %al
+; X64-NEXT:    retq
+  %tmp0 = add i16 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp uge i16 %tmp0, %y
+  ret i1 %tmp1
+}
+
+; Second constant is not larger than the first one
+define i1 @add_ugecmp_bad_i8_i16(i16 %x) nounwind {
+; X86-LABEL: add_ugecmp_bad_i8_i16:
+; X86:       # %bb.0:
+; X86-NEXT:    movl $128, %eax
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movzwl %ax, %eax
+; X86-NEXT:    cmpl $127, %eax
+; X86-NEXT:    seta %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ugecmp_bad_i8_i16:
+; X64:       # %bb.0:
+; X64-NEXT:    subl $-128, %edi
+; X64-NEXT:    movzwl %di, %eax
+; X64-NEXT:    cmpl $127, %eax
+; X64-NEXT:    seta %al
+; X64-NEXT:    retq
+  %tmp0 = add i16 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp uge i16 %tmp0, 128 ; 1U << (8-1)
+  ret i1 %tmp1
+}
+
+; First constant is not power of two
+define i1 @add_ugecmp_bad_i16_i8_c0notpoweroftwo(i16 %x) nounwind {
+; X86-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
+; X86:       # %bb.0:
+; X86-NEXT:    movl $192, %eax
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movzwl %ax, %eax
+; X86-NEXT:    cmpl $255, %eax
+; X86-NEXT:    seta %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
+; X64:       # %bb.0:
+; X64-NEXT:    addl $192, %edi
+; X64-NEXT:    movzwl %di, %eax
+; X64-NEXT:    cmpl $255, %eax
+; X64-NEXT:    seta %al
+; X64-NEXT:    retq
+  %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1))
+  %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}
+
+; Second constant is not power of two
+define i1 @add_ugecmp_bad_i16_i8_c1notpoweroftwo(i16 %x) nounwind {
+; X86-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
+; X86:       # %bb.0:
+; X86-NEXT:    movl $128, %eax
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movzwl %ax, %eax
+; X86-NEXT:    cmpl $767, %eax # imm = 0x2FF
+; X86-NEXT:    seta %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
+; X64:       # %bb.0:
+; X64-NEXT:    subl $-128, %edi
+; X64-NEXT:    movzwl %di, %eax
+; X64-NEXT:    cmpl $767, %eax # imm = 0x2FF
+; X64-NEXT:    seta %al
+; X64-NEXT:    retq
+  %tmp0 = add i16 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp uge i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1))
+  ret i1 %tmp1
+}
+
+; Magic check fails, 64 << 1 != 256
+define i1 @add_ugecmp_bad_i16_i8_magic(i16 %x) nounwind {
+; X86-LABEL: add_ugecmp_bad_i16_i8_magic:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    addl $64, %eax
+; X86-NEXT:    movzwl %ax, %eax
+; X86-NEXT:    cmpl $255, %eax
+; X86-NEXT:    seta %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ugecmp_bad_i16_i8_magic:
+; X64:       # %bb.0:
+; X64-NEXT:    addl $64, %edi
+; X64-NEXT:    movzwl %di, %eax
+; X64-NEXT:    cmpl $255, %eax
+; X64-NEXT:    seta %al
+; X64-NEXT:    retq
+  %tmp0 = add i16 %x, 64 ; 1U << (8-1-1)
+  %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}
+
+; Bad 'destination type'
+define i1 @add_ugecmp_bad_i16_i4(i16 %x) nounwind {
+; X86-LABEL: add_ugecmp_bad_i16_i4:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    addl $8, %eax
+; X86-NEXT:    movzwl %ax, %eax
+; X86-NEXT:    cmpl $15, %eax
+; X86-NEXT:    seta %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ugecmp_bad_i16_i4:
+; X64:       # %bb.0:
+; X64-NEXT:    addl $8, %edi
+; X64-NEXT:    movzwl %di, %eax
+; X64-NEXT:    cmpl $15, %eax
+; X64-NEXT:    seta %al
+; X64-NEXT:    retq
+  %tmp0 = add i16 %x, 8 ; 1U << (4-1)
+  %tmp1 = icmp uge i16 %tmp0, 16 ; 1U << 4
+  ret i1 %tmp1
+}
+
+; Bad storage type
+define i1 @add_ugecmp_bad_i24_i8(i24 %x) nounwind {
+; X86-LABEL: add_ugecmp_bad_i24_i8:
+; X86:       # %bb.0:
+; X86-NEXT:    movl $128, %eax
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    andl $16777215, %eax # imm = 0xFFFFFF
+; X86-NEXT:    cmpl $255, %eax
+; X86-NEXT:    seta %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ugecmp_bad_i24_i8:
+; X64:       # %bb.0:
+; X64-NEXT:    subl $-128, %edi
+; X64-NEXT:    andl $16777215, %edi # imm = 0xFFFFFF
+; X64-NEXT:    cmpl $255, %edi
+; X64-NEXT:    seta %al
+; X64-NEXT:    retq
+  %tmp0 = add i24 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp uge i24 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}

Modified: llvm/trunk/test/CodeGen/X86/signed-truncation-check.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/signed-truncation-check.ll?rev=337014&r1=337013&r2=337014&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/signed-truncation-check.ll (original)
+++ llvm/trunk/test/CodeGen/X86/signed-truncation-check.ll Fri Jul 13 09:14:37 2018
@@ -424,3 +424,184 @@ define i1 @add_ultcmp_i64_i8(i64 %x) nou
   %tmp1 = icmp ult i64 %tmp0, 256 ; 1U << 8
   ret i1 %tmp1
 }
+
+; Negative tests
+; ---------------------------------------------------------------------------- ;
+
+; Adding not a constant
+define i1 @add_ultcmp_bad_i16_i8_add(i16 %x, i16 %y) nounwind {
+; X86-LABEL: add_ultcmp_bad_i16_i8_add:
+; X86:       # %bb.0:
+; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    addw {{[0-9]+}}(%esp), %ax
+; X86-NEXT:    movzwl %ax, %eax
+; X86-NEXT:    cmpl $256, %eax # imm = 0x100
+; X86-NEXT:    setb %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ultcmp_bad_i16_i8_add:
+; X64:       # %bb.0:
+; X64-NEXT:    addl %esi, %edi
+; X64-NEXT:    movzwl %di, %eax
+; X64-NEXT:    cmpl $256, %eax # imm = 0x100
+; X64-NEXT:    setb %al
+; X64-NEXT:    retq
+  %tmp0 = add i16 %x, %y
+  %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}
+
+; Comparing not with a constant
+define i1 @add_ultcmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind {
+; X86-LABEL: add_ultcmp_bad_i16_i8_cmp:
+; X86:       # %bb.0:
+; X86-NEXT:    movl $128, %eax
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    cmpw {{[0-9]+}}(%esp), %ax
+; X86-NEXT:    setb %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ultcmp_bad_i16_i8_cmp:
+; X64:       # %bb.0:
+; X64-NEXT:    subl $-128, %edi
+; X64-NEXT:    cmpw %si, %di
+; X64-NEXT:    setb %al
+; X64-NEXT:    retq
+  %tmp0 = add i16 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp ult i16 %tmp0, %y
+  ret i1 %tmp1
+}
+
+; Second constant is not larger than the first one
+define i1 @add_ultcmp_bad_i8_i16(i16 %x) nounwind {
+; X86-LABEL: add_ultcmp_bad_i8_i16:
+; X86:       # %bb.0:
+; X86-NEXT:    movw $128, %ax
+; X86-NEXT:    addw {{[0-9]+}}(%esp), %ax
+; X86-NEXT:    setb %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ultcmp_bad_i8_i16:
+; X64:       # %bb.0:
+; X64-NEXT:    addw $128, %di
+; X64-NEXT:    setb %al
+; X64-NEXT:    retq
+  %tmp0 = add i16 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp ult i16 %tmp0, 128 ; 1U << (8-1)
+  ret i1 %tmp1
+}
+
+; First constant is not power of two
+define i1 @add_ultcmp_bad_i16_i8_c0notpoweroftwo(i16 %x) nounwind {
+; X86-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
+; X86:       # %bb.0:
+; X86-NEXT:    movl $192, %eax
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movzwl %ax, %eax
+; X86-NEXT:    cmpl $256, %eax # imm = 0x100
+; X86-NEXT:    setb %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
+; X64:       # %bb.0:
+; X64-NEXT:    addl $192, %edi
+; X64-NEXT:    movzwl %di, %eax
+; X64-NEXT:    cmpl $256, %eax # imm = 0x100
+; X64-NEXT:    setb %al
+; X64-NEXT:    retq
+  %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1))
+  %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}
+
+; Second constant is not power of two
+define i1 @add_ultcmp_bad_i16_i8_c1notpoweroftwo(i16 %x) nounwind {
+; X86-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
+; X86:       # %bb.0:
+; X86-NEXT:    movl $128, %eax
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movzwl %ax, %eax
+; X86-NEXT:    cmpl $768, %eax # imm = 0x300
+; X86-NEXT:    setb %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
+; X64:       # %bb.0:
+; X64-NEXT:    subl $-128, %edi
+; X64-NEXT:    movzwl %di, %eax
+; X64-NEXT:    cmpl $768, %eax # imm = 0x300
+; X64-NEXT:    setb %al
+; X64-NEXT:    retq
+  %tmp0 = add i16 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp ult i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1))
+  ret i1 %tmp1
+}
+
+; Magic check fails, 64 << 1 != 256
+define i1 @add_ultcmp_bad_i16_i8_magic(i16 %x) nounwind {
+; X86-LABEL: add_ultcmp_bad_i16_i8_magic:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    addl $64, %eax
+; X86-NEXT:    movzwl %ax, %eax
+; X86-NEXT:    cmpl $256, %eax # imm = 0x100
+; X86-NEXT:    setb %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ultcmp_bad_i16_i8_magic:
+; X64:       # %bb.0:
+; X64-NEXT:    addl $64, %edi
+; X64-NEXT:    movzwl %di, %eax
+; X64-NEXT:    cmpl $256, %eax # imm = 0x100
+; X64-NEXT:    setb %al
+; X64-NEXT:    retq
+  %tmp0 = add i16 %x, 64 ; 1U << (8-1-1)
+  %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}
+
+; Bad 'destination type'
+define i1 @add_ultcmp_bad_i16_i4(i16 %x) nounwind {
+; X86-LABEL: add_ultcmp_bad_i16_i4:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    addl $8, %eax
+; X86-NEXT:    movzwl %ax, %eax
+; X86-NEXT:    cmpl $16, %eax
+; X86-NEXT:    setb %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ultcmp_bad_i16_i4:
+; X64:       # %bb.0:
+; X64-NEXT:    addl $8, %edi
+; X64-NEXT:    movzwl %di, %eax
+; X64-NEXT:    cmpl $16, %eax
+; X64-NEXT:    setb %al
+; X64-NEXT:    retq
+  %tmp0 = add i16 %x, 8 ; 1U << (4-1)
+  %tmp1 = icmp ult i16 %tmp0, 16 ; 1U << 4
+  ret i1 %tmp1
+}
+
+; Bad storage type
+define i1 @add_ultcmp_bad_i24_i8(i24 %x) nounwind {
+; X86-LABEL: add_ultcmp_bad_i24_i8:
+; X86:       # %bb.0:
+; X86-NEXT:    movl $128, %eax
+; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    andl $16777215, %eax # imm = 0xFFFFFF
+; X86-NEXT:    cmpl $256, %eax # imm = 0x100
+; X86-NEXT:    setb %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: add_ultcmp_bad_i24_i8:
+; X64:       # %bb.0:
+; X64-NEXT:    subl $-128, %edi
+; X64-NEXT:    andl $16777215, %edi # imm = 0xFFFFFF
+; X64-NEXT:    cmpl $256, %edi # imm = 0x100
+; X64-NEXT:    setb %al
+; X64-NEXT:    retq
+  %tmp0 = add i24 %x, 128 ; 1U << (8-1)
+  %tmp1 = icmp ult i24 %tmp0, 256 ; 1U << 8
+  ret i1 %tmp1
+}




More information about the llvm-commits mailing list