Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / InstCombine / sink-not-into-another-hand-of-logical-or.ll
blob3985118ab085faaa3c6421bddbc55e8866c79ea2
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
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.
10 declare void @use1(i1)
11 declare void @use8(i8)
13 ; Most basic positive test
14 define 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:%.*]] = select i1 [[I0:%.*]], i1 [[I1]], i1 false
18 ; CHECK-NEXT:    [[I4:%.*]] = select i1 [[I3_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]]
19 ; CHECK-NEXT:    ret i8 [[I4]]
21   %i1 = icmp eq i8 %v0, %v1
22   %i2 = xor i1 %i0, -1
23   %i3 = select i1 %i2, i1 true, i1 %i1
24   %i4 = select i1 %i3, i8 %v2, i8 %v3
25   ret i8 %i4
27 define i8 @t0_commutative(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
28 ; CHECK-LABEL: @t0_commutative(
29 ; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V0:%.*]], [[V1:%.*]]
30 ; CHECK-NEXT:    [[I3_NOT:%.*]] = select i1 [[I1]], i1 [[I0:%.*]], i1 false
31 ; CHECK-NEXT:    [[I4:%.*]] = select i1 [[I3_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]]
32 ; CHECK-NEXT:    ret i8 [[I4]]
34   %i1 = icmp eq i8 %v0, %v1
35   %i2 = xor i1 %i0, -1
36   %i3 = select i1 %i1, i1 true, i1 %i2
37   %i4 = select i1 %i3, i8 %v2, i8 %v3
38   ret i8 %i4
40 define i8 @t1(i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
41 ; CHECK-LABEL: @t1(
42 ; CHECK-NEXT:    [[I0:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
43 ; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V2:%.*]], [[V3:%.*]]
44 ; CHECK-NEXT:    call void @use1(i1 [[I0]])
45 ; CHECK-NEXT:    [[I3_NOT:%.*]] = select i1 [[I0]], i1 [[I1]], i1 false
46 ; CHECK-NEXT:    [[I4:%.*]] = select i1 [[I3_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
47 ; CHECK-NEXT:    ret i8 [[I4]]
49   %i0 = icmp eq i8 %v0, %v1
50   %i1 = icmp eq i8 %v2, %v3
51   call void @use1(i1 %i0)
52   %i2 = xor i1 %i0, -1
53   %i3 = select i1 %i2, i1 true, i1 %i1
54   %i4 = select i1 %i3, i8 %v4, i8 %v5
55   ret i8 %i4
57 define i8 @t1_commutative(i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
58 ; CHECK-LABEL: @t1_commutative(
59 ; CHECK-NEXT:    [[I0:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
60 ; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V2:%.*]], [[V3:%.*]]
61 ; CHECK-NEXT:    call void @use1(i1 [[I0]])
62 ; CHECK-NEXT:    [[I3_NOT:%.*]] = select i1 [[I1]], i1 [[I0]], i1 false
63 ; CHECK-NEXT:    [[I4:%.*]] = select i1 [[I3_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
64 ; CHECK-NEXT:    ret i8 [[I4]]
66   %i0 = icmp eq i8 %v0, %v1
67   %i1 = icmp eq i8 %v2, %v3
68   call void @use1(i1 %i0)
69   %i2 = xor i1 %i0, -1
70   %i3 = select i1 %i1, i1 true, i1 %i2
71   %i4 = select i1 %i3, i8 %v4, i8 %v5
72   ret i8 %i4
75 ; All users of %i3 must be invertible
76 define i1 @n2(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
77 ; CHECK-LABEL: @n2(
78 ; CHECK-NEXT:    [[I1:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
79 ; CHECK-NEXT:    [[I2:%.*]] = xor i1 [[I0:%.*]], true
80 ; CHECK-NEXT:    [[I3:%.*]] = select i1 [[I2]], i1 true, i1 [[I1]]
81 ; CHECK-NEXT:    ret i1 [[I3]]
83   %i1 = icmp eq i8 %v0, %v1
84   %i2 = xor i1 %i0, -1
85   %i3 = select i1 %i2, i1 true, i1 %i1
86   ret i1 %i3 ; can not be inverted
89 ; %i1 must be invertible
90 define i8 @n3(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
91 ; CHECK-LABEL: @n3(
92 ; CHECK-NEXT:    [[I1:%.*]] = icmp eq i8 [[V0:%.*]], [[V1:%.*]]
93 ; CHECK-NEXT:    call void @use1(i1 [[I1]])
94 ; CHECK-NEXT:    [[I2:%.*]] = xor i1 [[I0:%.*]], true
95 ; CHECK-NEXT:    [[I3:%.*]] = select i1 [[I2]], i1 true, i1 [[I1]]
96 ; CHECK-NEXT:    [[I4:%.*]] = select i1 [[I3]], i8 [[V2:%.*]], i8 [[V3:%.*]]
97 ; CHECK-NEXT:    ret i8 [[I4]]
99   %i1 = icmp eq i8 %v0, %v1 ; has extra uninvertible use
100   call void @use1(i1 %i1) ; bad extra use
101   %i2 = xor i1 %i0, -1
102   %i3 = select i1 %i2, i1 true, i1 %i1
103   %i4 = select i1 %i3, i8 %v2, i8 %v3
104   ret i8 %i4
107 ; Extra uses are invertible
108 define i8 @t4(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
109 ; CHECK-LABEL: @t4(
110 ; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V0:%.*]], [[V1:%.*]]
111 ; CHECK-NEXT:    [[I2:%.*]] = select i1 [[I1]], i8 [[V3:%.*]], i8 [[V2:%.*]]
112 ; CHECK-NEXT:    call void @use8(i8 [[I2]])
113 ; CHECK-NEXT:    [[I4_NOT:%.*]] = select i1 [[I0:%.*]], i1 [[I1]], i1 false
114 ; CHECK-NEXT:    [[I5:%.*]] = select i1 [[I4_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
115 ; CHECK-NEXT:    ret i8 [[I5]]
117   %i1 = icmp eq i8 %v0, %v1 ; has extra invertible use
118   %i2 = select i1 %i1, i8 %v2, i8 %v3 ; invertible use
119   call void @use8(i8 %i2)
120   %i3 = xor i1 %i0, -1
121   %i4 = select i1 %i3, i1 true, i1 %i1
122   %i5 = select i1 %i4, i8 %v4, i8 %v5
123   ret i8 %i5
125 define i8 @t4_commutative(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
126 ; CHECK-LABEL: @t4_commutative(
127 ; CHECK-NEXT:    [[I1:%.*]] = icmp ne i8 [[V0:%.*]], [[V1:%.*]]
128 ; CHECK-NEXT:    [[I2:%.*]] = select i1 [[I1]], i8 [[V3:%.*]], i8 [[V2:%.*]]
129 ; CHECK-NEXT:    call void @use8(i8 [[I2]])
130 ; CHECK-NEXT:    [[I4_NOT:%.*]] = select i1 [[I1]], i1 [[I0:%.*]], i1 false
131 ; CHECK-NEXT:    [[I5:%.*]] = select i1 [[I4_NOT]], i8 [[V5:%.*]], i8 [[V4:%.*]]
132 ; CHECK-NEXT:    ret i8 [[I5]]
134   %i1 = icmp eq i8 %v0, %v1 ; has extra invertible use
135   %i2 = select i1 %i1, i8 %v2, i8 %v3 ; invertible use
136   call void @use8(i8 %i2)
137   %i3 = xor i1 %i0, -1
138   %i4 = select i1 %i1, i1 true, i1 %i3
139   %i5 = select i1 %i4, i8 %v4, i8 %v5
140   ret i8 %i5