1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
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) {
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
23 %i3 = select i1 %i2, i1 true, i1 %i1
24 %i4 = select i1 %i3, i8 %v2, i8 %v3
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
36 %i3 = select i1 %i1, i1 true, i1 %i2
37 %i4 = select i1 %i3, i8 %v2, i8 %v3
40 define i8 @t1(i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
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)
53 %i3 = select i1 %i2, i1 true, i1 %i1
54 %i4 = select i1 %i3, i8 %v4, i8 %v5
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)
70 %i3 = select i1 %i1, i1 true, i1 %i2
71 %i4 = select i1 %i3, i8 %v4, i8 %v5
75 ; All users of %i3 must be invertible
76 define i1 @n2(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
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
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) {
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
102 %i3 = select i1 %i2, i1 true, i1 %i1
103 %i4 = select i1 %i3, i8 %v2, i8 %v3
107 ; Extra uses are invertible
108 define i8 @t4(i1 %i0, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
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)
121 %i4 = select i1 %i3, i1 true, i1 %i1
122 %i5 = select i1 %i4, i8 %v4, i8 %v5
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)
138 %i4 = select i1 %i1, i1 true, i1 %i3
139 %i5 = select i1 %i4, i8 %v4, i8 %v5