xref: /llvm-project/llvm/test/Transforms/InstCombine/sink-not-into-another-hand-of-logical-and.ll (revision 3ae00753c156d70b3e7000451ac71391241ac5dd)
102a3e22cSRoman Lebedev; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
202a3e22cSRoman Lebedev; RUN: opt < %s -passes=instcombine -S | FileCheck %s
302a3e22cSRoman Lebedev
402a3e22cSRoman Lebedev; Transform
502a3e22cSRoman Lebedev;   z = (~x) & y
602a3e22cSRoman Lebedev; into:
702a3e22cSRoman Lebedev;   z = ~(x | (~y))
802a3e22cSRoman Lebedev; iff y is free to invert and all uses of z can be freely updated.
902a3e22cSRoman Lebedev
1002a3e22cSRoman Lebedevdeclare void @use1(i1)
11726130eeSRoman Lebedevdeclare void @use8(i8)
1202a3e22cSRoman Lebedev
1302a3e22cSRoman Lebedev; Most basic positive test
14726130eeSRoman Lebedevdefine i8 @t0(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
1502a3e22cSRoman Lebedev; CHECK-LABEL: @t0(
16726130eeSRoman Lebedev; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V0:%.*]], [[V1:%.*]]
179f0c9e47SRoman Lebedev; CHECK-NEXT:    [[I3_NOT:%.*]] = select i1 [[I0:%.*]], i1 true, i1 [[I1]]
18726130eeSRoman Lebedev; CHECK-NEXT:    [[I4:%.*]] = select i1 [[I3_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]]
19726130eeSRoman Lebedev; CHECK-NEXT:    ret i8 [[I4]]
2002a3e22cSRoman Lebedev;
21726130eeSRoman Lebedev  %i1 = icmp eq i8 %v0, %v1
2202a3e22cSRoman Lebedev  %i2 = xor i1 %i0, -1
2302a3e22cSRoman Lebedev  %i3 = select i1 %i2, i1 %i1, i1 false
24726130eeSRoman Lebedev  %i4 = select i1 %i3, i8 %v2, i8 %v3
25726130eeSRoman Lebedev  ret i8 %i4
2602a3e22cSRoman Lebedev}
27726130eeSRoman Lebedevdefine i8 @t0_commutative(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
2802a3e22cSRoman Lebedev; CHECK-LABEL: @t0_commutative(
29726130eeSRoman Lebedev; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V0:%.*]], [[V1:%.*]]
309f0c9e47SRoman Lebedev; CHECK-NEXT:    [[I3_NOT:%.*]] = select i1 [[I1]], i1 true, i1 [[I0:%.*]]
31726130eeSRoman Lebedev; CHECK-NEXT:    [[I4:%.*]] = select i1 [[I3_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]]
32726130eeSRoman Lebedev; CHECK-NEXT:    ret i8 [[I4]]
3302a3e22cSRoman Lebedev;
34726130eeSRoman Lebedev  %i1 = icmp eq i8 %v0, %v1
3502a3e22cSRoman Lebedev  %i2 = xor i1 %i0, -1
3602a3e22cSRoman Lebedev  %i3 = select i1 %i1, i1 %i2, i1 false
37726130eeSRoman Lebedev  %i4 = select i1 %i3, i8 %v2, i8 %v3
38726130eeSRoman Lebedev  ret i8 %i4
3902a3e22cSRoman Lebedev}
40726130eeSRoman Lebedevdefine i8 @t1(i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
4102a3e22cSRoman Lebedev; CHECK-LABEL: @t1(
42726130eeSRoman Lebedev; CHECK-NEXT:    [[I0:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
43726130eeSRoman Lebedev; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V2:%.*]], [[V3:%.*]]
446adeec88SRoman Lebedev; CHECK-NEXT:    call void @use1(i1 [[I0]])
45*3ae00753SRoman Lebedev; CHECK-NEXT:    [[I3_NOT:%.*]] = select i1 [[I0]], i1 true, i1 [[I1]]
46726130eeSRoman Lebedev; CHECK-NEXT:    [[I4:%.*]] = select i1 [[I3_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
47726130eeSRoman Lebedev; CHECK-NEXT:    ret i8 [[I4]]
4802a3e22cSRoman Lebedev;
49726130eeSRoman Lebedev  %i0 = icmp eq i8 %v0, %v1
50726130eeSRoman Lebedev  %i1 = icmp eq i8 %v2, %v3
5102a3e22cSRoman Lebedev  call void @use1(i1 %i0)
5202a3e22cSRoman Lebedev  %i2 = xor i1 %i0, -1
5302a3e22cSRoman Lebedev  %i3 = select i1 %i2, i1 %i1, i1 false
54726130eeSRoman Lebedev  %i4 = select i1 %i3, i8 %v4, i8 %v5
55726130eeSRoman Lebedev  ret i8 %i4
5602a3e22cSRoman Lebedev}
57726130eeSRoman Lebedevdefine i8 @t1_commutative(i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
5802a3e22cSRoman Lebedev; CHECK-LABEL: @t1_commutative(
59726130eeSRoman Lebedev; CHECK-NEXT:    [[I0:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
60726130eeSRoman Lebedev; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V2:%.*]], [[V3:%.*]]
616adeec88SRoman Lebedev; CHECK-NEXT:    call void @use1(i1 [[I0]])
62*3ae00753SRoman Lebedev; CHECK-NEXT:    [[I3_NOT:%.*]] = select i1 [[I1]], i1 true, i1 [[I0]]
63726130eeSRoman Lebedev; CHECK-NEXT:    [[I4:%.*]] = select i1 [[I3_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
64726130eeSRoman Lebedev; CHECK-NEXT:    ret i8 [[I4]]
6502a3e22cSRoman Lebedev;
66726130eeSRoman Lebedev  %i0 = icmp eq i8 %v0, %v1
67726130eeSRoman Lebedev  %i1 = icmp eq i8 %v2, %v3
6802a3e22cSRoman Lebedev  call void @use1(i1 %i0)
6902a3e22cSRoman Lebedev  %i2 = xor i1 %i0, -1
7002a3e22cSRoman Lebedev  %i3 = select i1 %i1, i1 %i2, i1 false
71726130eeSRoman Lebedev  %i4 = select i1 %i3, i8 %v4, i8 %v5
72726130eeSRoman Lebedev  ret i8 %i4
7302a3e22cSRoman Lebedev}
7402a3e22cSRoman Lebedev
7502a3e22cSRoman Lebedev; All users of %i3 must be invertible
76726130eeSRoman Lebedevdefine i1 @n2(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
7702a3e22cSRoman Lebedev; CHECK-LABEL: @n2(
78726130eeSRoman Lebedev; CHECK-NEXT:    [[I1:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
7902a3e22cSRoman Lebedev; CHECK-NEXT:    [[I2:%.*]] = xor i1 [[I0:%.*]], true
8002a3e22cSRoman Lebedev; CHECK-NEXT:    [[I3:%.*]] = select i1 [[I2]], i1 [[I1]], i1 false
8102a3e22cSRoman Lebedev; CHECK-NEXT:    ret i1 [[I3]]
8202a3e22cSRoman Lebedev;
83726130eeSRoman Lebedev  %i1 = icmp eq i8 %v0, %v1
8402a3e22cSRoman Lebedev  %i2 = xor i1 %i0, -1
8502a3e22cSRoman Lebedev  %i3 = select i1 %i2, i1 %i1, i1 false
8602a3e22cSRoman Lebedev  ret i1 %i3 ; can not be inverted
8702a3e22cSRoman Lebedev}
8802a3e22cSRoman Lebedev
8902a3e22cSRoman Lebedev; %i1 must be invertible
90726130eeSRoman Lebedevdefine i8 @n3(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
9102a3e22cSRoman Lebedev; CHECK-LABEL: @n3(
92726130eeSRoman Lebedev; CHECK-NEXT:    [[I1:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
9302a3e22cSRoman Lebedev; CHECK-NEXT:    call void @use1(i1 [[I1]])
9402a3e22cSRoman Lebedev; CHECK-NEXT:    [[I2:%.*]] = xor i1 [[I0:%.*]], true
9502a3e22cSRoman Lebedev; CHECK-NEXT:    [[I3:%.*]] = select i1 [[I2]], i1 [[I1]], i1 false
96726130eeSRoman Lebedev; CHECK-NEXT:    [[I4:%.*]] = select i1 [[I3]], i8 [[V2:%.*]], i8 [[V3:%.*]]
97726130eeSRoman Lebedev; CHECK-NEXT:    ret i8 [[I4]]
9802a3e22cSRoman Lebedev;
99726130eeSRoman Lebedev  %i1 = icmp eq i8 %v0, %v1 ; has extra uninvertible use
10002a3e22cSRoman Lebedev  call void @use1(i1 %i1) ; bad extra use
10102a3e22cSRoman Lebedev  %i2 = xor i1 %i0, -1
10202a3e22cSRoman Lebedev  %i3 = select i1 %i2, i1 %i1, i1 false
103726130eeSRoman Lebedev  %i4 = select i1 %i3, i8 %v2, i8 %v3
104726130eeSRoman Lebedev  ret i8 %i4
10502a3e22cSRoman Lebedev}
10602a3e22cSRoman Lebedev
107726130eeSRoman Lebedev; Extra uses are invertible
108726130eeSRoman Lebedevdefine i8 @t4(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
109726130eeSRoman Lebedev; CHECK-LABEL: @t4(
1106adeec88SRoman Lebedev; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V0:%.*]], [[V1:%.*]]
1116adeec88SRoman Lebedev; CHECK-NEXT:    [[I2:%.*]] = select i1 [[I1]], i8 [[V3:%.*]], i8 [[V2:%.*]]
112726130eeSRoman Lebedev; CHECK-NEXT:    call void @use8(i8 [[I2]])
113*3ae00753SRoman Lebedev; CHECK-NEXT:    [[I4_NOT:%.*]] = select i1 [[I0:%.*]], i1 true, i1 [[I1]]
1146adeec88SRoman Lebedev; CHECK-NEXT:    [[I5:%.*]] = select i1 [[I4_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
115726130eeSRoman Lebedev; CHECK-NEXT:    ret i8 [[I5]]
11602a3e22cSRoman Lebedev;
117726130eeSRoman Lebedev  %i1 = icmp eq i8 %v0, %v1 ; has extra invertible use
118726130eeSRoman Lebedev  %i2 = select i1 %i1, i8 %v2, i8 %v3 ; invertible use
119726130eeSRoman Lebedev  call void @use8(i8 %i2)
12002a3e22cSRoman Lebedev  %i3 = xor i1 %i0, -1
121726130eeSRoman Lebedev  %i4 = select i1 %i3, i1 %i1, i1 false
122726130eeSRoman Lebedev  %i5 = select i1 %i4, i8 %v4, i8 %v5
123726130eeSRoman Lebedev  ret i8 %i5
124726130eeSRoman Lebedev}
125726130eeSRoman Lebedevdefine i8 @t4_commutative(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
126726130eeSRoman Lebedev; CHECK-LABEL: @t4_commutative(
1276adeec88SRoman Lebedev; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V0:%.*]], [[V1:%.*]]
1286adeec88SRoman Lebedev; CHECK-NEXT:    [[I2:%.*]] = select i1 [[I1]], i8 [[V3:%.*]], i8 [[V2:%.*]]
129726130eeSRoman Lebedev; CHECK-NEXT:    call void @use8(i8 [[I2]])
130*3ae00753SRoman Lebedev; CHECK-NEXT:    [[I4_NOT:%.*]] = select i1 [[I1]], i1 true, i1 [[I0:%.*]]
1316adeec88SRoman Lebedev; CHECK-NEXT:    [[I5:%.*]] = select i1 [[I4_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
132726130eeSRoman Lebedev; CHECK-NEXT:    ret i8 [[I5]]
133726130eeSRoman Lebedev;
134726130eeSRoman Lebedev  %i1 = icmp eq i8 %v0, %v1 ; has extra invertible use
135726130eeSRoman Lebedev  %i2 = select i1 %i1, i8 %v2, i8 %v3 ; invertible use
136726130eeSRoman Lebedev  call void @use8(i8 %i2)
137726130eeSRoman Lebedev  %i3 = xor i1 %i0, -1
138726130eeSRoman Lebedev  %i4 = select i1 %i1, i1 %i3, i1 false
139726130eeSRoman Lebedev  %i5 = select i1 %i4, i8 %v4, i8 %v5
140726130eeSRoman Lebedev  ret i8 %i5
14102a3e22cSRoman Lebedev}
142