diff --git a/llvm/test/Transforms/InstCombine/APInt/.cvsignore b/llvm/test/Transforms/InstCombine/APInt/.cvsignore new file mode 100644 index 000000000000..7f2443f2f31a --- /dev/null +++ b/llvm/test/Transforms/InstCombine/APInt/.cvsignore @@ -0,0 +1,3 @@ +Output +*.log +*.sum diff --git a/llvm/test/Transforms/InstCombine/APInt/dg.exp b/llvm/test/Transforms/InstCombine/APInt/dg.exp new file mode 100644 index 000000000000..142de8a6c8f6 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/APInt/dg.exp @@ -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/llvm/test/Transforms/InstCombine/apint-add1.ll b/llvm/test/Transforms/InstCombine/apint-add1.ll new file mode 100644 index 000000000000..2473ec1403f5 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-add1.ll @@ -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/llvm/test/Transforms/InstCombine/apint-add2.ll b/llvm/test/Transforms/InstCombine/apint-add2.ll new file mode 100644 index 000000000000..f60e3bea1ec2 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-add2.ll @@ -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/llvm/test/Transforms/InstCombine/apint-and-compare.ll b/llvm/test/Transforms/InstCombine/apint-and-compare.ll new file mode 100644 index 000000000000..4d250a03772a --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-and-compare.ll @@ -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/llvm/test/Transforms/InstCombine/apint-and-or-and.ll b/llvm/test/Transforms/InstCombine/apint-and-or-and.ll new file mode 100644 index 000000000000..6bea6126cdce --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-and-or-and.ll @@ -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/llvm/test/Transforms/InstCombine/apint-and-xor-merge.ll b/llvm/test/Transforms/InstCombine/apint-and-xor-merge.ll new file mode 100644 index 000000000000..d2265ed4b670 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-and-xor-merge.ll @@ -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/llvm/test/Transforms/InstCombine/apint-and1.ll b/llvm/test/Transforms/InstCombine/apint-and1.ll new file mode 100644 index 000000000000..11e504a1824c --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-and1.ll @@ -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/llvm/test/Transforms/InstCombine/apint-and2.ll b/llvm/test/Transforms/InstCombine/apint-and2.ll new file mode 100644 index 000000000000..690f0e1df2fb --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-and2.ll @@ -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/llvm/test/Transforms/InstCombine/apint-binop-cast.ll b/llvm/test/Transforms/InstCombine/apint-binop-cast.ll new file mode 100644 index 000000000000..3198a8ac8d9d --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-binop-cast.ll @@ -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/llvm/test/Transforms/InstCombine/apint-call-cast-target.ll b/llvm/test/Transforms/InstCombine/apint-call-cast-target.ll new file mode 100644 index 000000000000..6201c72d85ba --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-call-cast-target.ll @@ -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/llvm/test/Transforms/InstCombine/apint-cast-and-cast.ll b/llvm/test/Transforms/InstCombine/apint-cast-and-cast.ll new file mode 100644 index 000000000000..337fd7c2d722 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-cast-and-cast.ll @@ -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/llvm/test/Transforms/InstCombine/apint-cast-cast-to-and.ll b/llvm/test/Transforms/InstCombine/apint-cast-cast-to-and.ll new file mode 100644 index 000000000000..29a88694d5c5 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-cast-cast-to-and.ll @@ -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/llvm/test/Transforms/InstCombine/apint-cast.ll b/llvm/test/Transforms/InstCombine/apint-cast.ll new file mode 100644 index 000000000000..9973b4aab1c2 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-cast.ll @@ -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 ; [#uses=2] + %tmp21 = lshr i37 %tmp, 8 ; [#uses=1] + %tmp5 = shl i37 %tmp, 8 ; [#uses=1] + %tmp.upgrd.32 = or i37 %tmp21, %tmp5 ; [#uses=1] + %tmp.upgrd.3 = trunc i37 %tmp.upgrd.32 to i17 ; [#uses=1] + ret i17 %tmp.upgrd.3 +} + +define i167 @test2(i167 %a) { + %tmp = zext i167 %a to i577 ; [#uses=2] + %tmp21 = lshr i577 %tmp, 9 ; [#uses=1] + %tmp5 = shl i577 %tmp, 8 ; [#uses=1] + %tmp.upgrd.32 = or i577 %tmp21, %tmp5 ; [#uses=1] + %tmp.upgrd.3 = trunc i577 %tmp.upgrd.32 to i167 ; [#uses=1] + ret i167 %tmp.upgrd.3 +} diff --git a/llvm/test/Transforms/InstCombine/apint-div1.ll b/llvm/test/Transforms/InstCombine/apint-div1.ll new file mode 100644 index 000000000000..b11b8bc24fb6 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-div1.ll @@ -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/llvm/test/Transforms/InstCombine/apint-div2.ll b/llvm/test/Transforms/InstCombine/apint-div2.ll new file mode 100644 index 000000000000..e83c97612d93 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-div2.ll @@ -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/llvm/test/Transforms/InstCombine/apint-mul1.ll b/llvm/test/Transforms/InstCombine/apint-mul1.ll new file mode 100644 index 000000000000..58f3bc9f3f09 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-mul1.ll @@ -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/llvm/test/Transforms/InstCombine/apint-mul2.ll b/llvm/test/Transforms/InstCombine/apint-mul2.ll new file mode 100644 index 000000000000..16518bb44e12 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-mul2.ll @@ -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/llvm/test/Transforms/InstCombine/apint-not.ll b/llvm/test/Transforms/InstCombine/apint-not.ll new file mode 100644 index 000000000000..89fc31b23034 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-not.ll @@ -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/llvm/test/Transforms/InstCombine/apint-or1.ll b/llvm/test/Transforms/InstCombine/apint-or1.ll new file mode 100644 index 000000000000..993a37685e2b --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-or1.ll @@ -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/llvm/test/Transforms/InstCombine/apint-or2.ll b/llvm/test/Transforms/InstCombine/apint-or2.ll new file mode 100644 index 000000000000..c0a9971ecfe8 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-or2.ll @@ -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/llvm/test/Transforms/InstCombine/apint-rem1.ll b/llvm/test/Transforms/InstCombine/apint-rem1.ll new file mode 100644 index 000000000000..0d72d447ffa3 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-rem1.ll @@ -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/llvm/test/Transforms/InstCombine/apint-rem2.ll b/llvm/test/Transforms/InstCombine/apint-rem2.ll new file mode 100644 index 000000000000..111a1b07fff9 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-rem2.ll @@ -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/llvm/test/Transforms/InstCombine/apint-select.ll b/llvm/test/Transforms/InstCombine/apint-select.ll new file mode 100644 index 000000000000..d804a34f6e4a --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-select.ll @@ -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 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 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/llvm/test/Transforms/InstCombine/apint-shl-trunc.ll b/llvm/test/Transforms/InstCombine/apint-shl-trunc.ll new file mode 100644 index 000000000000..cf5b1f868343 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-shl-trunc.ll @@ -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/llvm/test/Transforms/InstCombine/apint-sub.ll b/llvm/test/Transforms/InstCombine/apint-sub.ll new file mode 100644 index 000000000000..570e20fec5d1 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-sub.ll @@ -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 ; [#uses=1] + ret i23 %B +} + +define i47 @test2(i47 %A) { + %B = sub i47 %A, 0 ; [#uses=1] + ret i47 %B +} + +define i97 @test3(i97 %A) { + %B = sub i97 0, %A ; [#uses=1] + %C = sub i97 0, %B ; [#uses=1] + ret i97 %C +} + +define i108 @test4(i108 %A, i108 %x) { + %B = sub i108 0, %A ; [#uses=1] + %C = sub i108 %x, %B ; [#uses=1] + ret i108 %C +} + +define i19 @test5(i19 %A, i19 %Bok, i19 %Cok) { + %D = sub i19 %Bok, %Cok ; [#uses=1] + %E = sub i19 %A, %D ; [#uses=1] + ret i19 %E +} + +define i57 @test6(i57 %A, i57 %B) { + %C = and i57 %A, %B ; [#uses=1] + %D = sub i57 %A, %C ; [#uses=1] + ret i57 %D +} + +define i77 @test7(i77 %A) { + %B = sub i77 -1, %A ; [#uses=1] + ret i77 %B +} + +define i27 @test8(i27 %A) { + %B = mul i27 9, %A ; [#uses=1] + %C = sub i27 %B, %A ; [#uses=1] + ret i27 %C +} + +define i42 @test9(i42 %A) { + %B = mul i42 3, %A ; [#uses=1] + %C = sub i42 %A, %B ; [#uses=1] + ret i42 %C +} + +define i124 @test10(i124 %A, i124 %B) { + %C = sub i124 0, %A ; [#uses=1] + %D = sub i124 0, %B ; [#uses=1] + %E = mul i124 %C, %D ; [#uses=1] + ret i124 %E +} + +define i55 @test10a(i55 %A) { + %C = sub i55 0, %A ; [#uses=1] + %E = mul i55 %C, 7 ; [#uses=1] + ret i55 %E +} + +define i1 @test11(i9 %A, i9 %B) { + %C = sub i9 %A, %B ; [#uses=1] + %cD = icmp ne i9 %C, 0 ; [#uses=1] + ret i1 %cD +} + +define i43 @test12(i43 %A) { + %B = ashr i43 %A, 42 ; [#uses=1] + %C = sub i43 0, %B ; [#uses=1] + ret i43 %C +} + +define i79 @test13(i79 %A) { + %B = lshr i79 %A, 78 ; [#uses=1] + %C = sub i79 0, %B ; [#uses=1] + ret i79 %C +} + +define i1024 @test14(i1024 %A) { + %B = lshr i1024 %A, 1023 ; [#uses=1] + %C = bitcast i1024 %B to i1024 ; [#uses=1] + %D = sub i1024 0, %C ; [#uses=1] + ret i1024 %D +} + +define i14 @test15(i14 %A, i14 %B) { + %C = sub i14 0, %A ; [#uses=1] + %D = srem i14 %B, %C ; [#uses=1] + ret i14 %D +} + +define i51 @test16(i51 %A) { + %X = sdiv i51 %A, 1123 ; [#uses=1] + %Y = sub i51 0, %X ; [#uses=1] + ret i51 %Y +} + +define i25 @test17(i25 %A) { + %B = sub i25 0, %A ; [#uses=1] + %C = sdiv i25 %B, 1234 ; [#uses=1] + ret i25 %C +} + +define i128 @test18(i128 %Y) { + %tmp.4 = shl i128 %Y, 2 ; [#uses=1] + %tmp.12 = shl i128 %Y, 2 ; [#uses=1] + %tmp.8 = sub i128 %tmp.4, %tmp.12 ; [#uses=1] + ret i128 %tmp.8 +} + +define i39 @test19(i39 %X, i39 %Y) { + %Z = sub i39 %X, %Y ; [#uses=1] + %Q = add i39 %Z, %Y ; [#uses=1] + ret i39 %Q +} + +define i1 @test20(i33 %g, i33 %h) { + %tmp.2 = sub i33 %g, %h ; [#uses=1] + %tmp.4 = icmp ne i33 %tmp.2, %g ; [#uses=1] + ret i1 %tmp.4 +} + +define i1 @test21(i256 %g, i256 %h) { + %tmp.2 = sub i256 %g, %h ; [#uses=1] + %tmp.4 = icmp ne i256 %tmp.2, %g; [#uses=1] + ret i1 %tmp.4 +} diff --git a/llvm/test/Transforms/InstCombine/apint-xor1.ll b/llvm/test/Transforms/InstCombine/apint-xor1.ll new file mode 100644 index 000000000000..8daa9cc4426c --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-xor1.ll @@ -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/llvm/test/Transforms/InstCombine/apint-xor2.ll b/llvm/test/Transforms/InstCombine/apint-xor2.ll new file mode 100644 index 000000000000..91273243515b --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-xor2.ll @@ -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/llvm/test/Transforms/InstCombine/apint-zext1.ll b/llvm/test/Transforms/InstCombine/apint-zext1.ll new file mode 100644 index 000000000000..462e6910ca36 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-zext1.ll @@ -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/llvm/test/Transforms/InstCombine/apint-zext2.ll b/llvm/test/Transforms/InstCombine/apint-zext2.ll new file mode 100644 index 000000000000..ea6000926b5b --- /dev/null +++ b/llvm/test/Transforms/InstCombine/apint-zext2.ll @@ -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 +}