xref: /llvm-project/llvm/test/Transforms/InstCombine/or-xor-xor.ll (revision a105877646d68e48cdeeeadd9d1e075dc3c5d68d)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4declare void @use.i3(i1)
5declare void @use.i5(i5)
6declare void @use.i32(i5)
7
8define i1 @or_xor_xor_normal_variant1(i1 %a, i1 %b) {
9; CHECK-LABEL: @or_xor_xor_normal_variant1(
10; CHECK-NEXT:    [[OR:%.*]] = xor i1 [[A:%.*]], [[B:%.*]]
11; CHECK-NEXT:    ret i1 [[OR]]
12;
13  %and = and i1 %a, %b
14  %xor1 = xor i1 %and, %a
15  %xor2 = xor i1 %and, %b
16  %or = or i1 %xor1, %xor2
17  ret i1 %or
18}
19
20define i8 @or_xor_xor_normal_variant2(i8 %a, i8 %b) {
21; CHECK-LABEL: @or_xor_xor_normal_variant2(
22; CHECK-NEXT:    [[OR:%.*]] = xor i8 [[A:%.*]], [[B:%.*]]
23; CHECK-NEXT:    ret i8 [[OR]]
24;
25  %and = and i8 %a, %b
26  %xor1 = xor i8 %and, %b
27  %xor2 = xor i8 %a, %and
28  %or = or i8 %xor1, %xor2
29  ret i8 %or
30}
31
32define i16 @or_xor_xor_normal_variant3(i16 %a, i16 %b) {
33; CHECK-LABEL: @or_xor_xor_normal_variant3(
34; CHECK-NEXT:    [[OR:%.*]] = xor i16 [[B:%.*]], [[A:%.*]]
35; CHECK-NEXT:    ret i16 [[OR]]
36;
37  %and = and i16 %b, %a
38  %xor1 = xor i16 %b, %and
39  %xor2 = xor i16 %a, %and
40  %or = or i16 %xor1, %xor2
41  ret i16 %or
42}
43
44define i64 @or_xor_xor_normal_variant4(i64 %a, i64 %b) {
45; CHECK-LABEL: @or_xor_xor_normal_variant4(
46; CHECK-NEXT:    [[OR:%.*]] = xor i64 [[B:%.*]], [[A:%.*]]
47; CHECK-NEXT:    ret i64 [[OR]]
48;
49  %and = and i64 %b, %a
50  %xor1 = xor i64 %and, %b
51  %xor2 = xor i64 %and, %a
52  %or = or i64 %xor1, %xor2
53  ret i64 %or
54}
55
56define i32 @or_xor_xor_normal_binops(i32 %aa, i32 %bb, i32 %cc) {
57; CHECK-LABEL: @or_xor_xor_normal_binops(
58; CHECK-NEXT:    [[OR:%.*]] = xor i32 [[BB:%.*]], [[AA:%.*]]
59; CHECK-NEXT:    ret i32 [[OR]]
60;
61  %a = xor i32 %aa, %cc
62  %b = xor i32 %bb, %cc
63
64  %and = and i32 %b, %a
65  %xor1 = xor i32 %b, %and
66  %xor2 = xor i32 %a, %and
67  %or = or i32 %xor1, %xor2
68  ret i32 %or
69}
70
71define <3 x i1> @or_xor_xor_normal_vector(<3 x i1> %a, <3 x i1> %b) {
72; CHECK-LABEL: @or_xor_xor_normal_vector(
73; CHECK-NEXT:    [[OR:%.*]] = xor <3 x i1> [[A:%.*]], [[B:%.*]]
74; CHECK-NEXT:    ret <3 x i1> [[OR]]
75;
76  %and = and <3 x i1> %a, %b
77  %xor1 = xor <3 x i1> %and, %b
78  %xor2 = xor <3 x i1> %and, %a
79  %or = or <3 x i1> %xor1, %xor2
80  ret <3 x i1> %or
81}
82
83define i3 @or_xor_xor_normal_multiple_uses_and(i3 %a, i3 %b) {
84; CHECK-LABEL: @or_xor_xor_normal_multiple_uses_and(
85; CHECK-NEXT:    [[AND:%.*]] = and i3 [[A:%.*]], [[B:%.*]]
86; CHECK-NEXT:    call void @use.i3(i3 [[AND]])
87; CHECK-NEXT:    [[OR:%.*]] = xor i3 [[A]], [[B]]
88; CHECK-NEXT:    ret i3 [[OR]]
89;
90  %and = and i3 %a, %b
91  call void @use.i3(i3 %and)
92  %xor1 = xor i3 %b, %and
93  %xor2 = xor i3 %a, %and
94  %or = or i3 %xor1, %xor2
95  ret i3 %or
96}
97
98define i32 @or_xor_xor_negative_multiple_uses_xor1(i32 %a, i32 %b) {
99; CHECK-LABEL: @or_xor_xor_negative_multiple_uses_xor1(
100; CHECK-NEXT:    [[AND1:%.*]] = xor i32 [[A:%.*]], -1
101; CHECK-NEXT:    [[XOR1:%.*]] = and i32 [[B:%.*]], [[AND1]]
102; CHECK-NEXT:    call void @use.i32(i32 [[XOR1]])
103; CHECK-NEXT:    [[OR:%.*]] = xor i32 [[A]], [[B]]
104; CHECK-NEXT:    ret i32 [[OR]]
105;
106  %and = and i32 %a, %b
107  %xor1 = xor i32 %and, %b
108  call void @use.i32(i32 %xor1)
109  %xor2 = xor i32 %and, %a
110  %or = or i32 %xor1, %xor2
111  ret i32 %or
112}
113
114define i5 @or_xor_xor_negative_multiple_uses_xor2(i5 %a, i5 %b) {
115; CHECK-LABEL: @or_xor_xor_negative_multiple_uses_xor2(
116; CHECK-NEXT:    [[A1:%.*]] = xor i5 [[B:%.*]], -1
117; CHECK-NEXT:    [[XOR2:%.*]] = and i5 [[A:%.*]], [[A1]]
118; CHECK-NEXT:    call void @use.i5(i5 [[XOR2]])
119; CHECK-NEXT:    [[OR:%.*]] = xor i5 [[A]], [[B]]
120; CHECK-NEXT:    ret i5 [[OR]]
121;
122  %and = and i5 %a, %b
123  %xor1 = xor i5 %and, %b
124  %xor2 = xor i5 %and, %a
125  call void @use.i5(i5 %xor2)
126  %or = or i5 %xor1, %xor2
127  ret i5 %or
128}
129