mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-13 07:50:50 +00:00
cc54889cd5
(or (bool?A:B),(bool?C:D)) --> (bool?(or A,C):(or B,D)) By the time the OR is visited, both the SELECTs have been visited and not optimized and the OR itself hasn't been transformed so we do this transform in the hopes that the new ORs will be optimized. The transform is explicitly disabled for vector-selects until "codegen matures to handle them better". Patch by Muhammad Tauqir! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175380 91177308-0d34-0410-b5e6-96231b3b80d8
411 lines
8.8 KiB
LLVM
411 lines
8.8 KiB
LLVM
; This test makes sure that these instructions are properly eliminated.
|
|
; RUN: opt < %s -instcombine -S | FileCheck %s
|
|
|
|
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
|
|
|
define i32 @test1(i32 %A) {
|
|
%B = or i32 %A, 0
|
|
ret i32 %B
|
|
; CHECK: @test1
|
|
; CHECK: ret i32 %A
|
|
}
|
|
|
|
define i32 @test2(i32 %A) {
|
|
%B = or i32 %A, -1
|
|
ret i32 %B
|
|
; CHECK: @test2
|
|
; CHECK: ret i32 -1
|
|
}
|
|
|
|
define i8 @test2a(i8 %A) {
|
|
%B = or i8 %A, -1
|
|
ret i8 %B
|
|
; CHECK: @test2a
|
|
; CHECK: ret i8 -1
|
|
}
|
|
|
|
define i1 @test3(i1 %A) {
|
|
%B = or i1 %A, false
|
|
ret i1 %B
|
|
; CHECK: @test3
|
|
; CHECK: ret i1 %A
|
|
}
|
|
|
|
define i1 @test4(i1 %A) {
|
|
%B = or i1 %A, true
|
|
ret i1 %B
|
|
; CHECK: @test4
|
|
; CHECK: ret i1 true
|
|
}
|
|
|
|
define i1 @test5(i1 %A) {
|
|
%B = or i1 %A, %A
|
|
ret i1 %B
|
|
; CHECK: @test5
|
|
; CHECK: ret i1 %A
|
|
}
|
|
|
|
define i32 @test6(i32 %A) {
|
|
%B = or i32 %A, %A
|
|
ret i32 %B
|
|
; CHECK: @test6
|
|
; CHECK: ret i32 %A
|
|
}
|
|
|
|
; A | ~A == -1
|
|
define i32 @test7(i32 %A) {
|
|
%NotA = xor i32 -1, %A
|
|
%B = or i32 %A, %NotA
|
|
ret i32 %B
|
|
; CHECK: @test7
|
|
; CHECK: ret i32 -1
|
|
}
|
|
|
|
define i8 @test8(i8 %A) {
|
|
%B = or i8 %A, -2
|
|
%C = or i8 %B, 1
|
|
ret i8 %C
|
|
; CHECK: @test8
|
|
; CHECK: ret i8 -1
|
|
}
|
|
|
|
; Test that (A|c1)|(B|c2) == (A|B)|(c1|c2)
|
|
define i8 @test9(i8 %A, i8 %B) {
|
|
%C = or i8 %A, 1
|
|
%D = or i8 %B, -2
|
|
%E = or i8 %C, %D
|
|
ret i8 %E
|
|
; CHECK: @test9
|
|
; CHECK: ret i8 -1
|
|
}
|
|
|
|
define i8 @test10(i8 %A) {
|
|
%B = or i8 %A, 1
|
|
%C = and i8 %B, -2
|
|
; (X & C1) | C2 --> (X | C2) & (C1|C2)
|
|
%D = or i8 %C, -2
|
|
ret i8 %D
|
|
; CHECK: @test10
|
|
; CHECK: ret i8 -2
|
|
}
|
|
|
|
define i8 @test11(i8 %A) {
|
|
%B = or i8 %A, -2
|
|
%C = xor i8 %B, 13
|
|
; (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2)
|
|
%D = or i8 %C, 1
|
|
%E = xor i8 %D, 12
|
|
ret i8 %E
|
|
; CHECK: @test11
|
|
; CHECK: ret i8 -1
|
|
}
|
|
|
|
define i32 @test12(i32 %A) {
|
|
; Should be eliminated
|
|
%B = or i32 %A, 4
|
|
%C = and i32 %B, 8
|
|
ret i32 %C
|
|
; CHECK: @test12
|
|
; CHECK: %C = and i32 %A, 8
|
|
; CHECK: ret i32 %C
|
|
}
|
|
|
|
define i32 @test13(i32 %A) {
|
|
%B = or i32 %A, 12
|
|
; Always equal to 8
|
|
%C = and i32 %B, 8
|
|
ret i32 %C
|
|
; CHECK: @test13
|
|
; CHECK: ret i32 8
|
|
}
|
|
|
|
define i1 @test14(i32 %A, i32 %B) {
|
|
%C1 = icmp ult i32 %A, %B
|
|
%C2 = icmp ugt i32 %A, %B
|
|
; (A < B) | (A > B) === A != B
|
|
%D = or i1 %C1, %C2
|
|
ret i1 %D
|
|
; CHECK: @test14
|
|
; CHECK: icmp ne i32 %A, %B
|
|
; CHECK: ret i1
|
|
}
|
|
|
|
define i1 @test15(i32 %A, i32 %B) {
|
|
%C1 = icmp ult i32 %A, %B
|
|
%C2 = icmp eq i32 %A, %B
|
|
; (A < B) | (A == B) === A <= B
|
|
%D = or i1 %C1, %C2
|
|
ret i1 %D
|
|
; CHECK: @test15
|
|
; CHECK: icmp ule i32 %A, %B
|
|
; CHECK: ret i1
|
|
}
|
|
|
|
define i32 @test16(i32 %A) {
|
|
%B = and i32 %A, 1
|
|
; -2 = ~1
|
|
%C = and i32 %A, -2
|
|
; %D = and int %B, -1 == %B
|
|
%D = or i32 %B, %C
|
|
ret i32 %D
|
|
; CHECK: @test16
|
|
; CHECK: ret i32 %A
|
|
}
|
|
|
|
define i32 @test17(i32 %A) {
|
|
%B = and i32 %A, 1
|
|
%C = and i32 %A, 4
|
|
; %D = and int %B, 5
|
|
%D = or i32 %B, %C
|
|
ret i32 %D
|
|
; CHECK: @test17
|
|
; CHECK: %D = and i32 %A, 5
|
|
; CHECK: ret i32 %D
|
|
}
|
|
|
|
define i1 @test18(i32 %A) {
|
|
%B = icmp sge i32 %A, 100
|
|
%C = icmp slt i32 %A, 50
|
|
;; (A-50) >u 50
|
|
%D = or i1 %B, %C
|
|
ret i1 %D
|
|
; CHECK: @test18
|
|
; CHECK: add i32
|
|
; CHECK: icmp ugt
|
|
; CHECK: ret i1
|
|
}
|
|
|
|
define i1 @test19(i32 %A) {
|
|
%B = icmp eq i32 %A, 50
|
|
%C = icmp eq i32 %A, 51
|
|
;; (A-50) < 2
|
|
%D = or i1 %B, %C
|
|
ret i1 %D
|
|
; CHECK: @test19
|
|
; CHECK: add i32
|
|
; CHECK: icmp ult
|
|
; CHECK: ret i1
|
|
}
|
|
|
|
define i32 @test20(i32 %x) {
|
|
%y = and i32 %x, 123
|
|
%z = or i32 %y, %x
|
|
ret i32 %z
|
|
; CHECK: @test20
|
|
; CHECK: ret i32 %x
|
|
}
|
|
|
|
define i32 @test21(i32 %tmp.1) {
|
|
%tmp.1.mask1 = add i32 %tmp.1, 2
|
|
%tmp.3 = and i32 %tmp.1.mask1, -2
|
|
%tmp.5 = and i32 %tmp.1, 1
|
|
;; add tmp.1, 2
|
|
%tmp.6 = or i32 %tmp.5, %tmp.3
|
|
ret i32 %tmp.6
|
|
; CHECK: @test21
|
|
; CHECK: add i32 %{{[^,]*}}, 2
|
|
; CHECK: ret i32
|
|
}
|
|
|
|
define i32 @test22(i32 %B) {
|
|
%ELIM41 = and i32 %B, 1
|
|
%ELIM7 = and i32 %B, -2
|
|
%ELIM5 = or i32 %ELIM41, %ELIM7
|
|
ret i32 %ELIM5
|
|
; CHECK: @test22
|
|
; CHECK: ret i32 %B
|
|
}
|
|
|
|
define i16 @test23(i16 %A) {
|
|
%B = lshr i16 %A, 1
|
|
;; fold or into xor
|
|
%C = or i16 %B, -32768
|
|
%D = xor i16 %C, 8193
|
|
ret i16 %D
|
|
; CHECK: @test23
|
|
; CHECK: %B = lshr i16 %A, 1
|
|
; CHECK: %D = xor i16 %B, -24575
|
|
; CHECK: ret i16 %D
|
|
}
|
|
|
|
; PR1738
|
|
define i1 @test24(double %X, double %Y) {
|
|
%tmp9 = fcmp uno double %X, 0.000000e+00 ; <i1> [#uses=1]
|
|
%tmp13 = fcmp uno double %Y, 0.000000e+00 ; <i1> [#uses=1]
|
|
%bothcond = or i1 %tmp13, %tmp9 ; <i1> [#uses=1]
|
|
ret i1 %bothcond
|
|
|
|
; CHECK: @test24
|
|
; CHECK: = fcmp uno double %Y, %X
|
|
; CHECK: ret i1
|
|
}
|
|
|
|
; PR3266 & PR5276
|
|
define i1 @test25(i32 %A, i32 %B) {
|
|
%C = icmp eq i32 %A, 0
|
|
%D = icmp eq i32 %B, 57
|
|
%E = or i1 %C, %D
|
|
%F = xor i1 %E, -1
|
|
ret i1 %F
|
|
|
|
; CHECK: @test25
|
|
; CHECK: icmp ne i32 %A, 0
|
|
; CHECK-NEXT: icmp ne i32 %B, 57
|
|
; CHECK-NEXT: %F = and i1
|
|
; CHECK-NEXT: ret i1 %F
|
|
}
|
|
|
|
; PR5634
|
|
define i1 @test26(i32 %A, i32 %B) {
|
|
%C1 = icmp eq i32 %A, 0
|
|
%C2 = icmp eq i32 %B, 0
|
|
; (A == 0) & (A == 0) --> (A|B) == 0
|
|
%D = and i1 %C1, %C2
|
|
ret i1 %D
|
|
; CHECK: @test26
|
|
; CHECK: or i32 %A, %B
|
|
; CHECK: icmp eq i32 {{.*}}, 0
|
|
; CHECK: ret i1
|
|
}
|
|
|
|
define i1 @test27(i32* %A, i32* %B) {
|
|
%C1 = ptrtoint i32* %A to i32
|
|
%C2 = ptrtoint i32* %B to i32
|
|
%D = or i32 %C1, %C2
|
|
%E = icmp eq i32 %D, 0
|
|
ret i1 %E
|
|
; CHECK: @test27
|
|
; CHECK: icmp eq i32* %A, null
|
|
; CHECK: icmp eq i32* %B, null
|
|
; CHECK: and i1
|
|
; CHECK: ret i1
|
|
}
|
|
|
|
; PR5634
|
|
define i1 @test28(i32 %A, i32 %B) {
|
|
%C1 = icmp ne i32 %A, 0
|
|
%C2 = icmp ne i32 %B, 0
|
|
; (A != 0) | (A != 0) --> (A|B) != 0
|
|
%D = or i1 %C1, %C2
|
|
ret i1 %D
|
|
; CHECK: @test28
|
|
; CHECK: or i32 %A, %B
|
|
; CHECK: icmp ne i32 {{.*}}, 0
|
|
; CHECK: ret i1
|
|
}
|
|
|
|
define i1 @test29(i32* %A, i32* %B) {
|
|
%C1 = ptrtoint i32* %A to i32
|
|
%C2 = ptrtoint i32* %B to i32
|
|
%D = or i32 %C1, %C2
|
|
%E = icmp ne i32 %D, 0
|
|
ret i1 %E
|
|
; CHECK: @test29
|
|
; CHECK: icmp ne i32* %A, null
|
|
; CHECK: icmp ne i32* %B, null
|
|
; CHECK: or i1
|
|
; CHECK: ret i1
|
|
}
|
|
|
|
; PR4216
|
|
define i32 @test30(i32 %A) {
|
|
entry:
|
|
%B = or i32 %A, 32962
|
|
%C = and i32 %A, -65536
|
|
%D = and i32 %B, 40186
|
|
%E = or i32 %D, %C
|
|
ret i32 %E
|
|
; CHECK: @test30
|
|
; CHECK: %D = and i32 %A, -58312
|
|
; CHECK: %E = or i32 %D, 32962
|
|
; CHECK: ret i32 %E
|
|
}
|
|
|
|
; PR4216
|
|
define i64 @test31(i64 %A) nounwind readnone ssp noredzone {
|
|
%B = or i64 %A, 194
|
|
%D = and i64 %B, 250
|
|
|
|
%C = or i64 %A, 32768
|
|
%E = and i64 %C, 4294941696
|
|
|
|
%F = or i64 %D, %E
|
|
ret i64 %F
|
|
; CHECK: @test31
|
|
; CHECK-NEXT: %E = and i64 %A, 4294908984
|
|
; CHECK-NEXT: %F = or i64 %E, 32962
|
|
; CHECK-NEXT: ret i64 %F
|
|
}
|
|
|
|
define <4 x i32> @test32(<4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191) {
|
|
%and.i135 = sext <4 x i1> %and.i1352 to <4 x i32> ; <<4 x i32>> [#uses=2]
|
|
%and.i129 = and <4 x i32> %vecinit6.i176, %and.i135 ; <<4 x i32>> [#uses=1]
|
|
%neg.i = xor <4 x i32> %and.i135, <i32 -1, i32 -1, i32 -1, i32 -1> ; <<4 x i32>> [#uses=1]
|
|
%and.i = and <4 x i32> %vecinit6.i191, %neg.i ; <<4 x i32>> [#uses=1]
|
|
%or.i = or <4 x i32> %and.i, %and.i129 ; <<4 x i32>> [#uses=1]
|
|
ret <4 x i32> %or.i
|
|
; codegen is mature enough to handle vector selects.
|
|
; CHECK: @test32
|
|
; CHECK: select <4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191
|
|
}
|
|
|
|
define i1 @test33(i1 %X, i1 %Y) {
|
|
%a = or i1 %X, %Y
|
|
%b = or i1 %a, %X
|
|
ret i1 %b
|
|
; CHECK: @test33
|
|
; CHECK-NEXT: or i1 %X, %Y
|
|
; CHECK-NEXT: ret
|
|
}
|
|
|
|
define i32 @test34(i32 %X, i32 %Y) {
|
|
%a = or i32 %X, %Y
|
|
%b = or i32 %Y, %a
|
|
ret i32 %b
|
|
; CHECK: @test34
|
|
; CHECK-NEXT: or i32 %X, %Y
|
|
; CHECK-NEXT: ret
|
|
}
|
|
|
|
define i32 @test35(i32 %a, i32 %b) {
|
|
%1 = or i32 %a, 1135
|
|
%2 = or i32 %1, %b
|
|
ret i32 %2
|
|
; CHECK: @test35
|
|
; CHECK-NEXT: or i32 %a, %b
|
|
; CHECK-NEXT: or i32 %1, 1135
|
|
}
|
|
|
|
define i1 @test36(i32 %x) {
|
|
%cmp1 = icmp eq i32 %x, 23
|
|
%cmp2 = icmp eq i32 %x, 24
|
|
%ret1 = or i1 %cmp1, %cmp2
|
|
%cmp3 = icmp eq i32 %x, 25
|
|
%ret2 = or i1 %ret1, %cmp3
|
|
ret i1 %ret2
|
|
; CHECK: @test36
|
|
; CHECK-NEXT: %x.off = add i32 %x, -23
|
|
; CHECK-NEXT: icmp ult i32 %x.off, 3
|
|
; CHECK-NEXT: ret i1
|
|
}
|
|
|
|
define i32 @test37(i32* %xp, i32 %y) {
|
|
; CHECK: @test37
|
|
; CHECK: select i1 %tobool, i32 -1, i32 %x
|
|
%tobool = icmp ne i32 %y, 0
|
|
%sext = sext i1 %tobool to i32
|
|
%x = load i32* %xp
|
|
%or = or i32 %sext, %x
|
|
ret i32 %or
|
|
}
|
|
|
|
define i32 @test38(i32* %xp, i32 %y) {
|
|
; CHECK: @test38
|
|
; CHECK: select i1 %tobool, i32 -1, i32 %x
|
|
%tobool = icmp ne i32 %y, 0
|
|
%sext = sext i1 %tobool to i32
|
|
%x = load i32* %xp
|
|
%or = or i32 %x, %sext
|
|
ret i32 %or
|
|
}
|