xref: /llvm-project/llvm/test/Transforms/InstCombine/sink-not-into-another-hand-of-or.ll (revision 3ae00753c156d70b3e7000451ac71391241ac5dd)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4; Transform
5;   z = (~x) | y
6; into:
7;   z = ~(x & (~y))
8; iff y is free to invert and all uses of z can be freely updated.
9
10declare void @use1(i1)
11declare void @use8(i8)
12
13; Most basic positive test
14define i8 @t0(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
15; CHECK-LABEL: @t0(
16; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V0:%.*]], [[V1:%.*]]
17; CHECK-NEXT:    [[I3_NOT:%.*]] = and i1 [[I1]], [[I0:%.*]]
18; CHECK-NEXT:    [[I4:%.*]] = select i1 [[I3_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]]
19; CHECK-NEXT:    ret i8 [[I4]]
20;
21  %i1 = icmp eq i8 %v0, %v1
22  %i2 = xor i1 %i0, -1
23  %i3 = or i1 %i2, %i1
24  %i4 = select i1 %i3, i8 %v2, i8 %v3
25  ret i8 %i4
26}
27define i8 @t1(i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
28; CHECK-LABEL: @t1(
29; CHECK-NEXT:    [[I0:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
30; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V2:%.*]], [[V3:%.*]]
31; CHECK-NEXT:    call void @use1(i1 [[I0]])
32; CHECK-NEXT:    [[I3_NOT:%.*]] = and i1 [[I1]], [[I0]]
33; CHECK-NEXT:    [[I4:%.*]] = select i1 [[I3_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
34; CHECK-NEXT:    ret i8 [[I4]]
35;
36  %i0 = icmp eq i8 %v0, %v1
37  %i1 = icmp eq i8 %v2, %v3
38  call void @use1(i1 %i0)
39  %i2 = xor i1 %i0, -1
40  %i3 = or i1 %i2, %i1
41  %i4 = select i1 %i3, i8 %v4, i8 %v5
42  ret i8 %i4
43}
44
45; All users of %i3 must be invertible
46define i1 @n2(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
47; CHECK-LABEL: @n2(
48; CHECK-NEXT:    [[I1:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
49; CHECK-NEXT:    [[I2:%.*]] = xor i1 [[I0:%.*]], true
50; CHECK-NEXT:    [[I3:%.*]] = or i1 [[I1]], [[I2]]
51; CHECK-NEXT:    ret i1 [[I3]]
52;
53  %i1 = icmp eq i8 %v0, %v1
54  %i2 = xor i1 %i0, -1
55  %i3 = or i1 %i2, %i1
56  ret i1 %i3 ; can not be inverted
57}
58
59; %i1 must be invertible
60define i8 @n3(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
61; CHECK-LABEL: @n3(
62; CHECK-NEXT:    [[I1:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
63; CHECK-NEXT:    call void @use1(i1 [[I1]])
64; CHECK-NEXT:    [[I2:%.*]] = xor i1 [[I0:%.*]], true
65; CHECK-NEXT:    [[I3:%.*]] = or i1 [[I1]], [[I2]]
66; CHECK-NEXT:    [[I4:%.*]] = select i1 [[I3]], i8 [[V2:%.*]], i8 [[V3:%.*]]
67; CHECK-NEXT:    ret i8 [[I4]]
68;
69  %i1 = icmp eq i8 %v0, %v1 ; has extra uninvertible use
70  call void @use1(i1 %i1) ; bad extra use
71  %i2 = xor i1 %i0, -1
72  %i3 = or i1 %i2, %i1
73  %i4 = select i1 %i3, i8 %v2, i8 %v3
74  ret i8 %i4
75}
76
77; Extra uses are invertible
78define i8 @t4(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
79; CHECK-LABEL: @t4(
80; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V0:%.*]], [[V1:%.*]]
81; CHECK-NEXT:    [[I2:%.*]] = select i1 [[I1]], i8 [[V3:%.*]], i8 [[V2:%.*]]
82; CHECK-NEXT:    call void @use8(i8 [[I2]])
83; CHECK-NEXT:    [[I4_NOT:%.*]] = and i1 [[I1]], [[I0:%.*]]
84; CHECK-NEXT:    [[I5:%.*]] = select i1 [[I4_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
85; CHECK-NEXT:    ret i8 [[I5]]
86;
87  %i1 = icmp eq i8 %v0, %v1 ; has extra invertible use
88  %i2 = select i1 %i1, i8 %v2, i8 %v3 ; invertible use
89  call void @use8(i8 %i2)
90  %i3 = xor i1 %i0, -1
91  %i4 = or i1 %i3, %i1
92  %i5 = select i1 %i4, i8 %v4, i8 %v5
93  ret i8 %i5
94}
95define i8 @t4_commutative(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
96; CHECK-LABEL: @t4_commutative(
97; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V0:%.*]], [[V1:%.*]]
98; CHECK-NEXT:    [[I2:%.*]] = select i1 [[I1]], i8 [[V3:%.*]], i8 [[V2:%.*]]
99; CHECK-NEXT:    call void @use8(i8 [[I2]])
100; CHECK-NEXT:    [[I4_NOT:%.*]] = and i1 [[I1]], [[I0:%.*]]
101; CHECK-NEXT:    [[I5:%.*]] = select i1 [[I4_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
102; CHECK-NEXT:    ret i8 [[I5]]
103;
104  %i1 = icmp eq i8 %v0, %v1 ; has extra invertible use
105  %i2 = select i1 %i1, i8 %v2, i8 %v3 ; invertible use
106  call void @use8(i8 %i2)
107  %i3 = xor i1 %i0, -1
108  %i4 = or i1 %i1, %i3
109  %i5 = select i1 %i4, i8 %v4, i8 %v5
110  ret i8 %i5
111}
112