1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; Don't do anything for the fully-variable case.
5 define i4 @t0(i4 %x, i4 %y, i4 %z) {
7 ; CHECK-NEXT: [[I0:%.*]] = or i4 [[X:%.*]], [[Y:%.*]]
8 ; CHECK-NEXT: [[I1:%.*]] = xor i4 [[I0]], [[Z:%.*]]
9 ; CHECK-NEXT: ret i4 [[I1]]
16 ; If the second operands are immediate constants, we can perform the fold.
17 define i4 @t1(i4 %x) {
19 ; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[X:%.*]], 3
20 ; CHECK-NEXT: [[I1:%.*]] = xor i4 [[TMP1]], 6
21 ; CHECK-NEXT: ret i4 [[I1]]
23 %i0 = or i4 %x, 12 ; 0b1100
24 %i1 = xor i4 %i0, 10 ; 0b1010
28 ; Must not have extra uses.
29 define i4 @t2(i4 %x) {
31 ; CHECK-NEXT: [[I0:%.*]] = or i4 [[X:%.*]], -4
32 ; CHECK-NEXT: call void @use(i4 [[I0]])
33 ; CHECK-NEXT: [[I1:%.*]] = xor i4 [[I0]], -6
34 ; CHECK-NEXT: ret i4 [[I1]]
36 %i0 = or i4 %x, 12 ; 0b1100
37 call void @use(i4 %i0)
38 %i1 = xor i4 %i0, 10 ; 0b1010
42 ; Splat constants are fine too.
43 define <2 x i4> @t3(<2 x i4> %x) {
45 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], splat (i4 3)
46 ; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], splat (i4 6)
47 ; CHECK-NEXT: ret <2 x i4> [[I1]]
49 %i0 = or <2 x i4> %x, <i4 12, i4 12>
50 %i1 = xor <2 x i4> %i0, <i4 10, i4 10>
54 ; Non-splat constants are fine too.
55 define <2 x i4> @t4(<2 x i4> %x) {
57 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 5>
58 ; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], splat (i4 6)
59 ; CHECK-NEXT: ret <2 x i4> [[I1]]
61 %i0 = or <2 x i4> %x, <i4 12, i4 10>
62 %i1 = xor <2 x i4> %i0, <i4 10, i4 12>
66 ; Partially-undef constants are fine.
67 define <2 x i4> @t5(<2 x i4> %x) {
69 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 undef>
70 ; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 undef>
71 ; CHECK-NEXT: ret <2 x i4> [[I1]]
73 %i0 = or <2 x i4> %x, <i4 12, i4 12>
74 %i1 = xor <2 x i4> %i0, <i4 10, i4 undef>
77 define <2 x i4> @t6(<2 x i4> %x) {
79 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 0>
80 ; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 5>
81 ; CHECK-NEXT: ret <2 x i4> [[I1]]
83 %i0 = or <2 x i4> %x, <i4 12, i4 undef>
84 %i1 = xor <2 x i4> %i0, <i4 10, i4 10>
87 define <2 x i4> @t7(<2 x i4> %x) {
89 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 undef>
90 ; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 undef>
91 ; CHECK-NEXT: ret <2 x i4> [[I1]]
93 %i0 = or <2 x i4> %x, <i4 12, i4 undef>
94 %i1 = xor <2 x i4> %i0, <i4 10, i4 undef>
98 ; Partially-poison constants are fine.
99 define <2 x i4> @t8(<2 x i4> %x) {
101 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 undef>
102 ; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 poison>
103 ; CHECK-NEXT: ret <2 x i4> [[I1]]
105 %i0 = or <2 x i4> %x, <i4 12, i4 12>
106 %i1 = xor <2 x i4> %i0, <i4 10, i4 poison>
109 define <2 x i4> @t9(<2 x i4> %x) {
111 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 0>
112 ; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 5>
113 ; CHECK-NEXT: ret <2 x i4> [[I1]]
115 %i0 = or <2 x i4> %x, <i4 12, i4 poison>
116 %i1 = xor <2 x i4> %i0, <i4 10, i4 10>
119 define <2 x i4> @t10(<2 x i4> %x) {
121 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 undef>
122 ; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 poison>
123 ; CHECK-NEXT: ret <2 x i4> [[I1]]
125 %i0 = or <2 x i4> %x, <i4 12, i4 poison>
126 %i1 = xor <2 x i4> %i0, <i4 10, i4 poison>
130 ; Do not deal with general constant expressions.
131 @G = external global i32
132 @G2 = external global i32
133 define i4 @t11(i4 %x) {
135 ; CHECK-NEXT: [[I0:%.*]] = or i4 [[X:%.*]], -4
136 ; CHECK-NEXT: [[I1:%.*]] = xor i4 [[I0]], ptrtoint (ptr @G2 to i4)
137 ; CHECK-NEXT: ret i4 [[I1]]
140 %i1 = xor i4 %i0, ptrtoint (ptr @G2 to i4)
143 define i4 @t12(i4 %x) {
145 ; CHECK-NEXT: [[I0:%.*]] = or i4 [[X:%.*]], ptrtoint (ptr @G to i4)
146 ; CHECK-NEXT: [[I1:%.*]] = xor i4 [[I0]], -6
147 ; CHECK-NEXT: ret i4 [[I1]]
149 %i0 = or i4 %x, ptrtoint (ptr @G to i4)
153 define i4 @t13(i4 %x) {
155 ; CHECK-NEXT: [[I0:%.*]] = or i4 [[X:%.*]], ptrtoint (ptr @G to i4)
156 ; CHECK-NEXT: [[I1:%.*]] = xor i4 [[I0]], ptrtoint (ptr @G2 to i4)
157 ; CHECK-NEXT: ret i4 [[I1]]
159 %i0 = or i4 %x, ptrtoint (ptr @G to i4)
160 %i1 = xor i4 %i0, ptrtoint (ptr @G2 to i4)
164 declare void @use(i4)