Add test case for testing InstCombine with arbitrary precision integer
authorReid Spencer <rspencer@reidspencer.com>
Fri, 23 Mar 2007 20:48:34 +0000 (20:48 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Fri, 23 Mar 2007 20:48:34 +0000 (20:48 +0000)
types. These tests mimic the integer test cases in the normal InstCombine
test suite but use "strange" integer bit widths.

Most tests written by Zhou Sheng, a few by me.

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

30 files changed:
test/Transforms/InstCombine/APInt/.cvsignore [new file with mode: 0644]
test/Transforms/InstCombine/APInt/dg.exp [new file with mode: 0644]
test/Transforms/InstCombine/apint-add1.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-add2.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-and-compare.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-and-or-and.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-and-xor-merge.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-and1.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-and2.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-binop-cast.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-call-cast-target.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-cast-and-cast.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-cast-cast-to-and.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-cast.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-div1.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-div2.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-mul1.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-mul2.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-not.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-or1.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-or2.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-rem1.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-rem2.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-select.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-shl-trunc.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-sub.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-xor1.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-xor2.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-zext1.ll [new file with mode: 0644]
test/Transforms/InstCombine/apint-zext2.ll [new file with mode: 0644]

diff --git a/test/Transforms/InstCombine/APInt/.cvsignore b/test/Transforms/InstCombine/APInt/.cvsignore
new file mode 100644 (file)
index 0000000..7f2443f
--- /dev/null
@@ -0,0 +1,3 @@
+Output
+*.log
+*.sum
diff --git a/test/Transforms/InstCombine/APInt/dg.exp b/test/Transforms/InstCombine/APInt/dg.exp
new file mode 100644 (file)
index 0000000..142de8a
--- /dev/null
@@ -0,0 +1,3 @@
+load_lib llvm-dg.exp
+
+llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $srcdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext $llvmgcc_version
diff --git a/test/Transforms/InstCombine/apint-add1.ll b/test/Transforms/InstCombine/apint-add1.ll
new file mode 100644 (file)
index 0000000..2473ec1
--- /dev/null
@@ -0,0 +1,52 @@
+; This test makes sure that add instructions are properly eliminated.
+; This test is for Integer BitWidth <= 64 && BitWidth % 8 != 0.
+
+; RUN: llvm-as < %s | opt -instcombine -disable-output &&
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | \
+; RUN:    grep -v OK | not grep add
+
+implementation
+
+define i1 @test1(i1 %x) {
+        %tmp.2 = xor i1 %x, 1
+        ;; Add of sign bit -> xor of sign bit.
+        %tmp.4 = add i1 %tmp.2, 1
+        ret i1 %tmp.4
+}
+
+define i47 @test2(i47 %x) {
+        %tmp.2 = xor i47 %x, 70368744177664
+        ;; Add of sign bit -> xor of sign bit.
+        %tmp.4 = add i47 %tmp.2, 70368744177664
+        ret i47 %tmp.4
+}
+
+define i15 @test3(i15 %x) {
+        %tmp.2 = xor i15 %x, 16384
+        ;; Add of sign bit -> xor of sign bit.
+        %tmp.4 = add i15 %tmp.2, 16384
+        ret i15 %tmp.4
+}
+
+define i12 @test4(i12 %x) {
+        ;; If we have ADD(XOR(AND(X, 0xFF), 0xF..F80), 0x80), it's a sext.
+        %X = and i12 %x, 63
+        %tmp.2 = xor i12 %X, 4064    ; 0xFE0
+        %tmp.4 = add i12 %tmp.2, 32  ; 0x020
+        ret i12 %tmp.4
+}
+
+define i49 @test5(i49 %x) {
+        ;; If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext.
+        %X = and i49 %x, 16777215                     ; 0x0000000ffffff
+        %tmp.2 = xor i49 %X, 8388608                  ; 0x0000000800000
+        %tmp.4 = add i49 %tmp.2, -8388608             ; 0x1FFFFFF800000
+        ret i49 %tmp.4
+}
+
+define i49 @test6(i49 %x) {
+        ;; (x & 254)+1 -> (x & 254)|1
+        %tmp.2 = and i49 %x, 562949953421310
+        %tmp.4 = add i49 %tmp.2, 1
+        ret i49 %tmp.4
+}
diff --git a/test/Transforms/InstCombine/apint-add2.ll b/test/Transforms/InstCombine/apint-add2.ll
new file mode 100644 (file)
index 0000000..f60e3be
--- /dev/null
@@ -0,0 +1,56 @@
+; This test makes sure that add instructions are properly eliminated.
+; This test is for Integer BitWidth > 64 && BitWidth <= 1024.
+
+; RUN: llvm-as < %s | opt -instcombine -disable-output &&
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | \
+; RUN:    grep -v OK | not grep add
+
+implementation
+
+define i111 @test1(i111 %x) {
+        %tmp.2 = shl i111 1, 110
+        %tmp.4 = xor i111 %x, %tmp.2
+        ;; Add of sign bit -> xor of sign bit.
+        %tmp.6 = add i111 %tmp.4, %tmp.2
+        ret i111 %tmp.6
+}
+
+define i65 @test2(i65 %x) {
+        %tmp.0 = shl i65 1, 64
+        %tmp.2 = xor i65 %x, %tmp.0
+        ;; Add of sign bit -> xor of sign bit.
+        %tmp.4 = add i65 %tmp.2, %tmp.0
+        ret i65 %tmp.4
+}
+
+define i1024 @test3(i1024 %x) {
+        %tmp.0 = shl i1024 1, 1023
+        %tmp.2 = xor i1024 %x, %tmp.0
+        ;; Add of sign bit -> xor of sign bit.
+        %tmp.4 = add i1024 %tmp.2, %tmp.0
+        ret i1024 %tmp.4
+}
+
+define i128 @test4(i128 %x) {
+        ;; If we have ADD(XOR(AND(X, 0xFF), 0xF..F80), 0x80), it's a sext.
+        %tmp.5 = shl i128 1, 127
+        %tmp.1 = ashr i128 %tmp.5, 120
+        %tmp.2 = xor i128 %x, %tmp.1      
+        %tmp.4 = add i128 %tmp.2, %tmp.5
+        ret i128 %tmp.4
+}
+
+define i99 @test5(i99 %x) {
+        ;; If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext.
+        %X = and i99 %x, 562949953421311
+        %tmp.2 = xor i99 %X, 281474976710656 
+        %tmp.4 = add i99 %tmp.2, -281474976710656
+        ret i99 %tmp.4
+}
+
+define i77 @test6(i77 %x) {
+        ;; (x & 254)+1 -> (x & 254)|1
+        %tmp.2 = and i77 %x, 562949953421310
+        %tmp.4 = add i77 %tmp.2, 1
+        ret i77 %tmp.4
+}
diff --git a/test/Transforms/InstCombine/apint-and-compare.ll b/test/Transforms/InstCombine/apint-and-compare.ll
new file mode 100644 (file)
index 0000000..4d250a0
--- /dev/null
@@ -0,0 +1,16 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep and | wc -l | grep 2
+
+; Should be optimized to one and.
+define i1 @test1(i33 %a, i33 %b) {
+        %tmp1 = and i33 %a, 65280
+        %tmp3 = and i33 %b, 65280
+        %tmp = icmp ne i33 %tmp1, %tmp3
+        ret i1 %tmp
+}
+
+define i1 @test2(i999 %a, i999 %b) {
+        %tmp1 = and i999 %a, 65280
+        %tmp3 = and i999 %b, 65280
+        %tmp = icmp ne i999 %tmp1, %tmp3
+        ret i1 %tmp
+}
diff --git a/test/Transforms/InstCombine/apint-and-or-and.ll b/test/Transforms/InstCombine/apint-and-or-and.ll
new file mode 100644 (file)
index 0000000..6bea612
--- /dev/null
@@ -0,0 +1,49 @@
+; If we have an 'and' of the result of an 'or', and one of the 'or' operands
+; cannot have contributed any of the resultant bits, delete the or.  This
+; occurs for very common C/C++ code like this:
+;
+; struct foo { int A : 16; int B : 16; };
+; void test(struct foo *F, int X, int Y) {
+;        F->A = X; F->B = Y;
+; }
+;
+; Which corresponds to test1.
+; 
+; This tests arbitrary precision integers.
+
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep 'or '
+
+define i17 @test1(i17 %X, i17 %Y) {
+       %A = and i17 %X, 7
+       %B = and i17 %Y, 8
+       %C = or i17 %A, %B
+       %D = and i17 %C, 7  ;; This cannot include any bits from %Y!
+       ret i17 %D
+}
+
+define i49 @test3(i49 %X, i49 %Y) {
+       %B = shl i49 %Y, 1
+       %C = or i49 %X, %B
+       %D = and i49 %C, 1  ;; This cannot include any bits from %Y!
+       ret i49 %D
+}
+
+define i67 @test4(i67 %X, i67 %Y) {
+       %B = lshr i67 %Y, 66
+       %C = or i67 %X, %B
+       %D = and i67 %C, 2  ;; This cannot include any bits from %Y!
+       ret i67 %D
+}
+
+define i231 @or_test1(i231 %X, i231 %Y) {
+       %A = and i231 %X, 1
+       %B = or i231 %A, 1     ;; This cannot include any bits from X!
+       ret i231 %B
+}
+
+define i7 @or_test2(i7 %X, i7 %Y) {
+       %A = shl i7 %X, 6
+       %B = or i7 %A, 64     ;; This cannot include any bits from X!
+       ret i7 %B
+}
+
diff --git a/test/Transforms/InstCombine/apint-and-xor-merge.ll b/test/Transforms/InstCombine/apint-and-xor-merge.ll
new file mode 100644 (file)
index 0000000..d2265ed
--- /dev/null
@@ -0,0 +1,22 @@
+; This test case checks that the merge of and/xor can work on arbitrary
+; precision integers.
+
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep and | wc -l | grep 1 &&
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep xor | wc -l | grep 2
+
+; (x &z ) ^ (y & z) -> (x ^ y) & z
+define i57 @test1(i57 %x, i57 %y, i57 %z) {
+        %tmp3 = and i57 %z, %x
+        %tmp6 = and i57 %z, %y
+        %tmp7 = xor i57 %tmp3, %tmp6
+        ret i57 %tmp7
+}
+
+; (x & y) ^ (x | y) -> x ^ y
+define i23 @test2(i23 %x, i23 %y, i23 %z) {
+        %tmp3 = and i23 %y, %x
+        %tmp6 = or i23 %y, %x
+        %tmp7 = xor i23 %tmp3, %tmp6
+        ret i23 %tmp7
+}
+
diff --git a/test/Transforms/InstCombine/apint-and1.ll b/test/Transforms/InstCombine/apint-and1.ll
new file mode 100644 (file)
index 0000000..11e504a
--- /dev/null
@@ -0,0 +1,59 @@
+; This test makes sure that and instructions are properly eliminated.
+; This test is for Integer BitWidth <= 64 && BitWidth % 8 != 0.
+
+; RUN: llvm-as < %s | opt -instcombine -disable-output &&
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep 'and '
+
+implementation
+
+define i39 @test0(i39 %A) {
+        %B = and i39 %A, 0 ; zero result
+        ret i39 %B
+}
+
+define i47 @test1(i47 %A, i47 %B) {
+        ;; (~A & ~B) == (~(A | B)) - De Morgan's Law
+        %NotA = xor i47 %A, -1
+        %NotB = xor i47 %B, -1
+        %C1 = and i47 %NotA, %NotB
+        ret i47 %C1
+}
+
+define i15 @test2(i15 %x) {
+        %tmp.2 = and i15 %x, -1 ; noop
+        ret i15 %tmp.2
+}
+
+define i23 @test3(i23 %x) {
+        %tmp.0 = and i23 %x, 127
+        %tmp.2 = and i23 %tmp.0, 128
+        ret i23 %tmp.2
+}
+
+define i1 @test4(i37 %x) {
+        %A = and i37 %x, -2147483648
+        %B = icmp ne i37 %A, 0
+        ret i1 %B
+}
+
+define i7 @test5(i7 %A, i7* %P) {
+        %B = or i7 %A, 3
+        %C = xor i7 %B, 12
+        store i7 %C, i7* %P
+        %r = and i7 %C, 3
+        ret i7 %r
+}
+
+define i7 @test6(i7 %A, i7 %B) {
+        ;; ~(~X & Y) --> (X | ~Y)
+        %t0 = xor i7 %A, -1
+        %t1 = and i7 %t0, %B
+        %r = xor i7 %t1, -1
+        ret i7 %r
+}
+
+define i47 @test7(i47 %A) {
+        %X = ashr i47 %A, 39 ;; sign extend
+        %C1 = and i47 %X, 255
+        ret i47 %C1
+}
diff --git a/test/Transforms/InstCombine/apint-and2.ll b/test/Transforms/InstCombine/apint-and2.ll
new file mode 100644 (file)
index 0000000..690f0e1
--- /dev/null
@@ -0,0 +1,83 @@
+; This test makes sure that and instructions are properly eliminated.
+; This test is for Integer BitWidth > 64 && BitWidth <= 1024.
+
+; RUN: llvm-as < %s | opt -instcombine -disable-output &&
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep 'and '
+
+implementation
+
+define i999 @test0(i999 %A) {
+        %B = and i999 %A, 0 ; zero result
+        ret i999 %B
+}
+
+define i477 @test1(i477 %A, i477 %B) {
+        ;; (~A & ~B) == (~(A | B)) - De Morgan's Law
+        %NotA = xor i477 %A, -1
+        %NotB = xor i477 %B, -1
+        %C1 = and i477 %NotA, %NotB
+        ret i477 %C1
+}
+
+define i129 @tst(i129 %A, i129 %B) {
+        ;; (~A & ~B) == (~(A | B)) - De Morgan's Law
+        %NotA = xor i129 %A, -1
+        %NotB = xor i129 %B, -1
+        %C1 = and i129 %NotA, %NotB
+        ret i129 %C1
+}
+
+define i65 @test(i65 %A, i65 %B) {
+        ;; (~A & ~B) == (~(A | B)) - De Morgan's Law
+        %NotA = xor i65 %A, -1
+        %NotB = xor i65 -1, %B
+        %C1 = and i65 %NotA, %NotB
+        ret i65 %C1
+}
+
+define i66 @tes(i66 %A, i66 %B) {
+        ;; (~A & ~B) == (~(A | B)) - De Morgan's Law
+        %NotA = xor i66 %A, -1
+        %NotB = xor i66 %B, -1
+        %C1 = and i66 %NotA, %NotB
+        ret i66 %C1
+}
+
+define i1005 @test2(i1005 %x) {
+        %tmp.2 = and i1005 %x, -1 ; noop
+        ret i1005 %tmp.2
+}
+
+define i123 @test3(i123 %x) {
+        %tmp.0 = and i123 %x, 127
+        %tmp.2 = and i123 %tmp.0, 128
+        ret i123 %tmp.2
+}
+
+define i1 @test4(i737 %x) {
+        %A = and i737 %x, -2147483648
+        %B = icmp ne i737 %A, 0
+        ret i1 %B
+}
+
+define i117 @test5(i117 %A, i117* %P) {
+        %B = or i117 %A, 3
+        %C = xor i117 %B, 12
+        store i117 %C, i117* %P
+        %r = and i117 %C, 3
+        ret i117 %r
+}
+
+define i117 @test6(i117 %A, i117 %B) {
+        ;; ~(~X & Y) --> (X | ~Y)
+        %t0 = xor i117 %A, -1
+        %t1 = and i117 %t0, %B
+        %r = xor i117 %t1, -1
+        ret i117 %r
+}
+
+define i1024 @test7(i1024 %A) {
+        %X = ashr i1024 %A, 1016 ;; sign extend
+        %C1 = and i1024 %X, 255
+        ret i1024 %C1
+}
diff --git a/test/Transforms/InstCombine/apint-binop-cast.ll b/test/Transforms/InstCombine/apint-binop-cast.ll
new file mode 100644 (file)
index 0000000..3198a8a
--- /dev/null
@@ -0,0 +1,13 @@
+; RUN: llvm-upgrade < %s | llvm-as | opt -instcombine | llvm-dis | notcast
+
+define i47 @testAdd(i31 %X, i31 %Y) {
+       %tmp = add i31 %X, %Y
+       %tmp.l = sext i31 %tmp to i47
+       ret i47 %tmp.l
+}
+
+define i747 @testAdd2(i131 %X, i131 %Y) {
+       %tmp = add i131 %X, %Y
+       %tmp.l = sext i131 %tmp to i747
+       ret i747 %tmp.l
+}
diff --git a/test/Transforms/InstCombine/apint-call-cast-target.ll b/test/Transforms/InstCombine/apint-call-cast-target.ll
new file mode 100644 (file)
index 0000000..6201c72
--- /dev/null
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep call | not grep bitcast
+
+target datalayout = "e-p:32:32"
+target triple = "i686-pc-linux-gnu"
+
+implementation   ; Functions:
+
+define i32 @main() {
+entry:
+       %tmp = call i32 bitcast (i7* (i999*)* @ctime to i32 (i99*)*)( i99* null )
+       ret i32 %tmp
+}
+
+declare i7* @ctime(i999*)
diff --git a/test/Transforms/InstCombine/apint-cast-and-cast.ll b/test/Transforms/InstCombine/apint-cast-and-cast.ll
new file mode 100644 (file)
index 0000000..337fd7c
--- /dev/null
@@ -0,0 +1,15 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep bitcast
+
+define i19 @test1(i43 %val) {
+  %t1 = bitcast i43 %val to i43 
+  %t2 = and i43 %t1, 1
+  %t3 = trunc i43 %t2 to i19
+  ret i19 %t3
+}
+
+define i73 @test2(i677 %val) {
+  %t1 = bitcast i677 %val to i677 
+  %t2 = and i677 %t1, 1
+  %t3 = trunc i677 %t2 to i73
+  ret i73 %t3
+}
diff --git a/test/Transforms/InstCombine/apint-cast-cast-to-and.ll b/test/Transforms/InstCombine/apint-cast-cast-to-and.ll
new file mode 100644 (file)
index 0000000..29a8869
--- /dev/null
@@ -0,0 +1,8 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep i41
+
+define i61 @test1(i61 %X) {
+        %Y = trunc i61 %X to i41 ;; Turn i61o an AND
+        %Z = zext i41 %Y to i61
+        ret i61 %Z
+}
+
diff --git a/test/Transforms/InstCombine/apint-cast.ll b/test/Transforms/InstCombine/apint-cast.ll
new file mode 100644 (file)
index 0000000..9973b4a
--- /dev/null
@@ -0,0 +1,21 @@
+; Tests to make sure elimination of casts is working correctly
+; RUN: llvm-as < %s | opt -instcombine -disable-output &&
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | notcast
+
+define i17 @test1(i17 %a) {
+        %tmp = zext i17 %a to i37               ; <i37> [#uses=2]
+        %tmp21 = lshr i37 %tmp, 8               ; <i37> [#uses=1]
+        %tmp5 = shl i37 %tmp, 8         ; <i37> [#uses=1]
+        %tmp.upgrd.32 = or i37 %tmp21, %tmp5            ; <i37> [#uses=1]
+        %tmp.upgrd.3 = trunc i37 %tmp.upgrd.32 to i17   ; <i17> [#uses=1]
+        ret i17 %tmp.upgrd.3
+}
+
+define i167 @test2(i167 %a) {
+        %tmp = zext i167 %a to i577               ; <i577> [#uses=2]
+        %tmp21 = lshr i577 %tmp, 9               ; <i577> [#uses=1]
+        %tmp5 = shl i577 %tmp, 8         ; <i577> [#uses=1]
+        %tmp.upgrd.32 = or i577 %tmp21, %tmp5            ; <i577> [#uses=1]
+        %tmp.upgrd.3 = trunc i577 %tmp.upgrd.32 to i167  ; <i167> [#uses=1]
+        ret i167 %tmp.upgrd.3
+}
diff --git a/test/Transforms/InstCombine/apint-div1.ll b/test/Transforms/InstCombine/apint-div1.ll
new file mode 100644 (file)
index 0000000..b11b8bc
--- /dev/null
@@ -0,0 +1,24 @@
+; This test makes sure that div instructions are properly eliminated.
+; This test is for Integer BitWidth < 64 && BitWidth % 2 != 0.
+;
+
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep div
+
+implementation
+
+define i33 @test1(i33 %X) {
+    %Y = udiv i33 %X, 4096
+    ret i33 %Y
+}
+
+define i49 @test2(i49 %X) {
+    %tmp.0 = shl i49 4096, 17
+    %Y = udiv i49 %X, %tmp.0
+    ret i49 %Y
+}
+
+define i59 @test3(i59 %X, bool %C) {
+        %V = select bool %C, i59 1024, i59 4096
+        %R = udiv i59 %X, %V
+        ret i59 %R
+}
diff --git a/test/Transforms/InstCombine/apint-div2.ll b/test/Transforms/InstCombine/apint-div2.ll
new file mode 100644 (file)
index 0000000..e83c976
--- /dev/null
@@ -0,0 +1,24 @@
+; This test makes sure that div instructions are properly eliminated.
+; This test is for Integer BitWidth >= 64 && BitWidth <= 1024.
+;
+
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep div
+
+implementation
+
+define i333 @test1(i333 %X) {
+    %Y = udiv i333 %X, 70368744177664
+    ret i333 %Y
+}
+
+define i499 @test2(i499 %X) {
+    %tmp.0 = shl i499 4096, 197
+    %Y = udiv i499 %X, %tmp.0
+    ret i499 %Y
+}
+
+define i599 @test3(i599 %X, bool %C) {
+        %V = select bool %C, i599 70368744177664, i599 4096
+        %R = udiv i599 %X, %V
+        ret i599 %R
+}
diff --git a/test/Transforms/InstCombine/apint-mul1.ll b/test/Transforms/InstCombine/apint-mul1.ll
new file mode 100644 (file)
index 0000000..58f3bc9
--- /dev/null
@@ -0,0 +1,12 @@
+; This test makes sure that mul instructions are properly eliminated.
+; This test is for Integer BitWidth < 64 && BitWidth % 2 != 0.
+;
+
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep mul
+
+implementation
+
+define i17 @test1(i17 %X) {
+    %Y = mul i17 %X, 1024
+    ret i17 %Y
+} 
diff --git a/test/Transforms/InstCombine/apint-mul2.ll b/test/Transforms/InstCombine/apint-mul2.ll
new file mode 100644 (file)
index 0000000..16518bb
--- /dev/null
@@ -0,0 +1,13 @@
+; This test makes sure that mul instructions are properly eliminated.
+; This test is for Integer BitWidth >= 64 && BitWidth % 2 >= 1024.
+;
+
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep mul
+
+implementation
+
+define i177 @test1(i177 %X) {
+    %C = shl i177 1, 155
+    %Y = mul i177 %X, %C
+    ret i177 %Y
+} 
diff --git a/test/Transforms/InstCombine/apint-not.ll b/test/Transforms/InstCombine/apint-not.ll
new file mode 100644 (file)
index 0000000..89fc31b
--- /dev/null
@@ -0,0 +1,42 @@
+; This test makes sure that the xor instructions are properly eliminated
+; when arbitrary precision integers are used.
+
+; RUN: llvm-as | opt -instcombine | llvm-dis | not grep xor
+
+define i33 @test1(i33 %A) {
+       %B = xor i33 %A, -1
+       %C = xor i33 %B, -1
+       ret i33 %C
+}
+
+define i1 @test2(i52 %A, i52 %B) {
+       %cond = icmp ule i52 %A, %B     ; Can change into uge
+       %Ret = xor i1 %cond, true
+       ret i1 %Ret
+}
+
+; Test that demorgans law can be instcombined
+define i47 @test3(i47 %A, i47 %B) {
+       %a = xor i47 %A, -1
+       %b = xor i47 %B, -1
+       %c = and i47 %a, %b
+       %d = xor i47 %c, -1
+       ret i47 %d
+}
+
+; Test that demorgens law can work with constants
+define i61 @test4(i61 %A, i61 %B) {
+       %a = xor i61 %A, -1
+       %c = and i61 %a, 5    ; 5 = ~c2
+       %d = xor i61 %c, -1
+       ret i61 %d
+}
+
+; test the mirror of demorgans law...
+define i71 @test5(i71 %A, i71 %B) {
+       %a = xor i71 %A, -1
+       %b = xor i71 %B, -1
+       %c = or i71 %a, %b
+       %d = xor i71 %c, -1
+       ret i71 %d
+}
diff --git a/test/Transforms/InstCombine/apint-or1.ll b/test/Transforms/InstCombine/apint-or1.ll
new file mode 100644 (file)
index 0000000..993a376
--- /dev/null
@@ -0,0 +1,37 @@
+; This test makes sure that or instructions are properly eliminated.
+; This test is for Integer BitWidth <= 64 && BitWidth % 2 != 0.
+;
+
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep or
+
+implementation
+
+define i7 @test0(i7 %X) {
+    %Y = or i7 %X, 0
+    ret i7 %Y
+}
+
+define i17 @test1(i17 %X) {
+    %Y = or i17 %X, -1
+    ret i17 %Y
+} 
+
+define i23 @test2(i23 %A) {
+    ;; A | ~A == -1
+    %NotA = xor i23 -1, %A
+    %B = or i23 %A, %NotA
+    ret i23 %B
+}
+
+define i39 @test3(i39 %V, i39 %M) {
+    ;; If we have: ((V + N) & C1) | (V & C2)
+    ;; .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0
+    ;; replace with V+N.
+    %C1 = xor i39 274877906943, -1 ;; C2 = 274877906943
+    %N = and i39 %M, 274877906944
+    %A = add i39 %V, %N
+    %B = and i39 %A, %C1
+    %D = and i39 %V, 274877906943
+    %R = or i39 %B, %D
+    ret i39 %R
+}
diff --git a/test/Transforms/InstCombine/apint-or2.ll b/test/Transforms/InstCombine/apint-or2.ll
new file mode 100644 (file)
index 0000000..c0a9971
--- /dev/null
@@ -0,0 +1,38 @@
+; This test makes sure that or instructions are properly eliminated.
+; This test is for Integer BitWidth > 64 && BitWidth <= 1024.
+;
+
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis > /tmp/or2.rel &&
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep or
+
+implementation
+
+define i777 @test0(i777 %X) {
+    %Y = or i777 %X, 0
+    ret i777 %Y
+}
+
+define i117 @test1(i117 %X) {
+    %Y = or i117 %X, -1
+    ret i117 %Y
+} 
+
+define i1023 @test2(i1023 %A) {
+    ;; A | ~A == -1
+    %NotA = xor i1023 -1, %A
+    %B = or i1023 %A, %NotA
+    ret i1023 %B
+}
+
+define i399 @test3(i399 %V, i399 %M) {
+    ;; If we have: ((V + N) & C1) | (V & C2)
+    ;; .. and C2 = ~C1 and C2 is 0+1+ and (N & C2) == 0
+    ;; replace with V+N.
+    %C1 = xor i399 274877906943, -1 ;; C2 = 274877906943
+    %N = and i399 %M, 18446742974197923840
+    %A = add i399 %V, %N
+    %B = and i399 %A, %C1
+    %D = and i399 %V, 274877906943
+    %R = or i399 %B, %D
+    ret i399 %R
+}
diff --git a/test/Transforms/InstCombine/apint-rem1.ll b/test/Transforms/InstCombine/apint-rem1.ll
new file mode 100644 (file)
index 0000000..0d72d44
--- /dev/null
@@ -0,0 +1,24 @@
+; This test makes sure that these instructions are properly eliminated.
+; This test is for Integer BitWidth < 64 && BitWidth % 2 != 0.
+;
+; RUN: llvm-as < %s | opt -instcombine -disable-output &&
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep rem
+
+implementation
+
+define i33 @test1(i33 %A) {
+    %B = urem i33 %A, 4096
+    ret i33 %B
+}
+
+define i49 @test2(i49 %A) {
+    %B = shl i49 4096, 11
+    %Y = urem i49 %A, %B
+    ret i49 %Y
+}
+
+define i59 @test3(i59 %X, i1 %C) {
+       %V = select i1 %C, i59 70368744177664, i59 4096
+       %R = urem i59 %X, %V
+       ret i59 %R
+}
diff --git a/test/Transforms/InstCombine/apint-rem2.ll b/test/Transforms/InstCombine/apint-rem2.ll
new file mode 100644 (file)
index 0000000..111a1b0
--- /dev/null
@@ -0,0 +1,24 @@
+; This test makes sure that these instructions are properly eliminated.
+; This test is for Integer BitWidth >= 64 && BitWidth <= 1024.
+;
+; RUN: llvm-as < %s | opt -instcombine -disable-output &&
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep rem
+
+implementation
+
+define i333 @test1(i333 %A) {
+    %B = urem i333 %A, 70368744177664
+    ret i333 %B
+}
+
+define i499 @test2(i499 %A) {
+    %B = shl i499 4096, 111
+    %Y = urem i499 %A, %B
+    ret i499 %Y
+}
+
+define i599 @test3(i599 %X, i1 %C) {
+       %V = select i1 %C, i599 70368744177664, i599 4096
+       %R = urem i599 %X, %V
+       ret i599 %R
+}
diff --git a/test/Transforms/InstCombine/apint-select.ll b/test/Transforms/InstCombine/apint-select.ll
new file mode 100644 (file)
index 0000000..d804a34
--- /dev/null
@@ -0,0 +1,46 @@
+; This test makes sure that these instructions are properly eliminated.
+
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep select &&
+; RUN: llvm-as < %s | opt -instcombine -disable-output
+
+implementation
+
+define i41 @test1(i1 %C) {
+       %V = select i1 %C, i41 1, i41 0  ; V = C
+       ret i41 %V
+}
+
+define i999 @test2(i1 %C) {
+       %V = select i1 %C, i999 0, i999 1  ; V = C
+       ret i999 %V
+}
+
+define i41 @test3(i41 %X) {
+    ;; (x <s 0) ? -1 : 0 -> ashr x, 31
+    %t = icmp slt i41 %X, 0
+    %V = select i1 %t, i41 -1, i41 0
+    ret i41 %V
+}
+
+define i1023 @test4(i1023 %X) {
+    ;; (x <s 0) ? -1 : 0 -> ashr x, 31
+    %t = icmp slt i1023 %X, 0
+    %V = select i1 %t, i1023 -1, i1023 0
+    ret i1023 %V
+}
+
+define i41 @test5(i41 %X) {
+    ;; ((X & 27) ? 27 : 0)
+    %Y = and i41 %X, 32
+    %t = icmp ne i41 %Y, 0
+    %V = select i1 %t, i41 32, i41 0
+    ret i41 %V
+}
+
+define i1023 @test6(i1023 %X) {
+    ;; ((X & 27) ? 27 : 0)
+    %Y = and i1023 %X, 64 
+    %t = icmp ne i1023 %Y, 0
+    %V = select i1 %t, i1023 64, i1023 0
+    ret i1023 %V
+}
diff --git a/test/Transforms/InstCombine/apint-shl-trunc.ll b/test/Transforms/InstCombine/apint-shl-trunc.ll
new file mode 100644 (file)
index 0000000..cf5b1f8
--- /dev/null
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis > /tmp/sht.rel &&
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep shl
+
+define i1 @test0(i39 %X, i39 %A) {
+       %B = lshr i39 %X, %A
+       %D = trunc i39 %B to i1
+       ret i1 %D
+}
+
+define i1 @test1(i799 %X, i799 %A) {
+       %B = lshr i799 %X, %A
+       %D = trunc i799 %B to i1
+       ret i1 %D
+}
diff --git a/test/Transforms/InstCombine/apint-sub.ll b/test/Transforms/InstCombine/apint-sub.ll
new file mode 100644 (file)
index 0000000..570e20f
--- /dev/null
@@ -0,0 +1,138 @@
+; This test makes sure that sub instructions are properly eliminated
+; even with arbitrary precision integers.
+;
+
+; RUN:  llvm-as | opt -instcombine | llvm-dis | \
+; RUN:   grep -v 'sub i19 %Cok, %Bok' | not grep sub
+
+define i23 @test1(i23 %A) {
+       %B = sub i23 %A, %A             ; <i23> [#uses=1]
+       ret i23 %B
+}
+
+define i47 @test2(i47 %A) {
+       %B = sub i47 %A, 0              ; <i47> [#uses=1]
+       ret i47 %B
+}
+
+define i97 @test3(i97 %A) {
+       %B = sub i97 0, %A              ; <i97> [#uses=1]
+       %C = sub i97 0, %B              ; <i97> [#uses=1]
+       ret i97 %C
+}
+
+define i108 @test4(i108 %A, i108 %x) {
+       %B = sub i108 0, %A             ; <i108> [#uses=1]
+       %C = sub i108 %x, %B            ; <i108> [#uses=1]
+       ret i108 %C
+}
+
+define i19 @test5(i19 %A, i19 %Bok, i19 %Cok) {
+       %D = sub i19 %Bok, %Cok         ; <i19> [#uses=1]
+       %E = sub i19 %A, %D             ; <i19> [#uses=1]
+       ret i19 %E
+}
+
+define i57 @test6(i57 %A, i57 %B) {
+       %C = and i57 %A, %B             ; <i57> [#uses=1]
+       %D = sub i57 %A, %C             ; <i57> [#uses=1]
+       ret i57 %D
+}
+
+define i77 @test7(i77 %A) {
+       %B = sub i77 -1, %A             ; <i77> [#uses=1]
+       ret i77 %B
+}
+
+define i27 @test8(i27 %A) {
+       %B = mul i27 9, %A              ; <i27> [#uses=1]
+       %C = sub i27 %B, %A             ; <i27> [#uses=1]
+       ret i27 %C
+}
+
+define i42 @test9(i42 %A) {
+       %B = mul i42 3, %A              ; <i42> [#uses=1]
+       %C = sub i42 %A, %B             ; <i42> [#uses=1]
+       ret i42 %C
+}
+
+define i124 @test10(i124 %A, i124 %B) {
+       %C = sub i124 0, %A             ; <i124> [#uses=1]
+       %D = sub i124 0, %B             ; <i124> [#uses=1]
+       %E = mul i124 %C, %D            ; <i124> [#uses=1]
+       ret i124 %E
+}
+
+define i55 @test10a(i55 %A) {
+       %C = sub i55 0, %A              ; <i55> [#uses=1]
+       %E = mul i55 %C, 7              ; <i55> [#uses=1]
+       ret i55 %E
+}
+
+define i1 @test11(i9 %A, i9 %B) {
+       %C = sub i9 %A, %B              ; <i9> [#uses=1]
+       %cD = icmp ne i9 %C, 0          ; <i1> [#uses=1]
+       ret i1 %cD
+}
+
+define i43 @test12(i43 %A) {
+       %B = ashr i43 %A, 42            ; <i43> [#uses=1]
+       %C = sub i43 0, %B              ; <i43> [#uses=1]
+       ret i43 %C
+}
+
+define i79 @test13(i79 %A) {
+       %B = lshr i79 %A, 78            ; <i79> [#uses=1]
+       %C = sub i79 0, %B              ; <i79> [#uses=1]
+       ret i79 %C
+}
+
+define i1024 @test14(i1024 %A) {
+       %B = lshr i1024 %A, 1023        ; <i1024> [#uses=1]
+       %C = bitcast i1024 %B to i1024  ; <i1024> [#uses=1]
+       %D = sub i1024 0, %C            ; <i1024> [#uses=1]
+       ret i1024 %D
+}
+
+define i14 @test15(i14 %A, i14 %B) {
+       %C = sub i14 0, %A              ; <i14> [#uses=1]
+       %D = srem i14 %B, %C            ; <i14> [#uses=1]
+       ret i14 %D
+}
+
+define i51 @test16(i51 %A) {
+       %X = sdiv i51 %A, 1123          ; <i51> [#uses=1]
+       %Y = sub i51 0, %X              ; <i51> [#uses=1]
+       ret i51 %Y
+}
+
+define i25 @test17(i25 %A) {
+       %B = sub i25 0, %A              ; <i25> [#uses=1]
+       %C = sdiv i25 %B, 1234          ; <i25> [#uses=1]
+       ret i25 %C
+}
+
+define i128 @test18(i128 %Y) {
+       %tmp.4 = shl i128 %Y, 2         ; <i128> [#uses=1]
+       %tmp.12 = shl i128 %Y, 2        ; <i128> [#uses=1]
+       %tmp.8 = sub i128 %tmp.4, %tmp.12       ; <i128> [#uses=1]
+       ret i128 %tmp.8
+}
+
+define i39 @test19(i39 %X, i39 %Y) {
+       %Z = sub i39 %X, %Y             ; <i39> [#uses=1]
+       %Q = add i39 %Z, %Y             ; <i39> [#uses=1]
+       ret i39 %Q
+}
+
+define i1 @test20(i33 %g, i33 %h) {
+       %tmp.2 = sub i33 %g, %h         ; <i33> [#uses=1]
+       %tmp.4 = icmp ne i33 %tmp.2, %g         ; <i1> [#uses=1]
+       ret i1 %tmp.4
+}
+
+define i1 @test21(i256 %g, i256 %h) {
+       %tmp.2 = sub i256 %g, %h        ; <i256> [#uses=1]
+       %tmp.4 = icmp ne i256 %tmp.2, %g; <i1> [#uses=1]
+       ret i1 %tmp.4
+}
diff --git a/test/Transforms/InstCombine/apint-xor1.ll b/test/Transforms/InstCombine/apint-xor1.ll
new file mode 100644 (file)
index 0000000..8daa9cc
--- /dev/null
@@ -0,0 +1,52 @@
+; This test makes sure that xor instructions are properly eliminated.
+; This test is for Integer BitWidth <= 64 && BitWidth % 8 != 0.
+
+; RUN: llvm-as < %s | opt -instcombine -disable-output &&
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep 'xor '
+
+implementation
+
+define i47 @test1(i47 %A, i47 %B) {
+        ;; (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
+        %A1 = and i47 %A, 70368744177664
+        %B1 = and i47 %B, 70368744177663
+        %C1 = xor i47 %A1, %B1
+        ret i47 %C1
+}
+
+define i15 @test2(i15 %x) {
+        %tmp.2 = xor i15 %x, 0
+        ret i15 %tmp.2
+}
+
+define i23 @test3(i23 %x) {
+        %tmp.2 = xor i23 %x, %x
+        ret i23 %tmp.2
+}
+
+define i37 @test4(i37 %x) {
+        ; x ^ ~x == -1
+        %NotX = xor i37 -1, %x
+        %B = xor i37 %x, %NotX
+        ret i37 %B
+}
+
+define i7 @test5(i7 %A) {
+        ;; (A|B)^B == A & (~B)
+        %t1 = or i7 %A, 23
+        %r = xor i7 %t1, 23
+        ret i7 %r
+}
+
+define i7 @test6(i7 %A) {
+        %t1 = xor i7 %A, 23
+        %r = xor i7 %t1, 23
+        ret i7 %r
+}
+
+define i47 @test7(i47 %A) {
+        ;; (A | C1) ^ C2 -> (A | C1) & ~C2 iff (C1&C2) == C2
+        %B1 = or i47 %A,   70368744177663
+        %C1 = xor i47 %B1, 703687463
+        ret i47 %C1
+}
diff --git a/test/Transforms/InstCombine/apint-xor2.ll b/test/Transforms/InstCombine/apint-xor2.ll
new file mode 100644 (file)
index 0000000..9127324
--- /dev/null
@@ -0,0 +1,52 @@
+; This test makes sure that xor instructions are properly eliminated.
+; This test is for Integer BitWidth > 64 && BitWidth <= 1024.
+
+; RUN: llvm-as < %s | opt -instcombine -disable-output &&
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep 'xor '
+
+implementation
+
+define i447 @test1(i447 %A, i447 %B) {
+        ;; (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
+        %A1 = and i447 %A, 70368744177664
+        %B1 = and i447 %B, 70368744177663
+        %C1 = xor i447 %A1, %B1
+        ret i447 %C1
+}
+
+define i1005 @test2(i1005 %x) {
+        %tmp.2 = xor i1005 %x, 0
+        ret i1005 %tmp.2
+}
+
+define i123 @test3(i123 %x) {
+        %tmp.2 = xor i123 %x, %x
+        ret i123 %tmp.2
+}
+
+define i737 @test4(i737 %x) {
+        ; x ^ ~x == -1
+        %NotX = xor i737 -1, %x
+        %B = xor i737 %x, %NotX
+        ret i737 %B
+}
+
+define i700 @test5(i700 %A) {
+        ;; (A|B)^B == A & (~B)
+        %t1 = or i700 %A, 288230376151711743 
+        %r = xor i700 %t1, 288230376151711743 
+        ret i700 %r
+}
+
+define i77 @test6(i77 %A) {
+        %t1 = xor i77 %A, 23
+        %r = xor i77 %t1, 23
+        ret i77 %r
+}
+
+define i1023 @test7(i1023 %A) {
+        ;; (A | C1) ^ C2 -> (A | C1) & ~C2 iff (C1&C2) == C2
+        %B1 = or i1023 %A,   70368744177663
+        %C1 = xor i1023 %B1, 703687463
+        ret i1023 %C1
+}
diff --git a/test/Transforms/InstCombine/apint-zext1.ll b/test/Transforms/InstCombine/apint-zext1.ll
new file mode 100644 (file)
index 0000000..462e691
--- /dev/null
@@ -0,0 +1,10 @@
+; Tests to make sure elimination of casts is working correctly
+; This test is for Integer BitWidth <= 64 && BitWidth % 2 != 0.
+; RUN: llvm-as < %s | opt -instcombine -disable-output &&
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | notcast '' '%c1.*'
+
+define i47 @test_sext_zext(i11 %A) {
+    %c1 = zext i11 %A to i39
+    %c2 = sext i39 %c1 to i47
+    ret i47 %c2
+}
diff --git a/test/Transforms/InstCombine/apint-zext2.ll b/test/Transforms/InstCombine/apint-zext2.ll
new file mode 100644 (file)
index 0000000..ea60009
--- /dev/null
@@ -0,0 +1,10 @@
+; Tests to make sure elimination of casts is working correctly
+; This test is for Integer BitWidth > 64 && BitWidth <= 1024.
+; RUN: llvm-as < %s | opt -instcombine -disable-output &&
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | notcast '' '%c1.*'
+
+define i1024 @test_sext_zext(i77 %A) {
+    %c1 = zext i77 %A to i533
+    %c2 = sext i533 %c1 to i1024
+    ret i1024 %c2
+}