xref: /llvm-project/llvm/test/Transforms/InstCombine/fold-a-or-b-zero.ll (revision f7fc72e281e26082d98b26c95c7ffc93393b3920)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2; RUN: opt < %s -S -passes=instcombine | FileCheck %s
3
4declare void @use(i1)
5
6define i1 @a_or_b(i32 %a, i32 %b)  {
7; CHECK-LABEL: define i1 @a_or_b(
8; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
9; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[A]], 0
10; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[B]], 0
11; CHECK-NEXT:    [[OR:%.*]] = xor i1 [[TMP1]], [[TMP2]]
12; CHECK-NEXT:    ret i1 [[OR]]
13;
14  %a_eq_zero = icmp eq i32 %a, 0
15  %b_ne_zero = icmp ne i32 %b, 0
16  %and.1 = and i1 %a_eq_zero, %b_ne_zero
17  %a_ne_zero = icmp ne i32 %a, 0
18  %b_eq_zero = icmp eq i32 %b, 0
19  %and.2 = and i1 %a_ne_zero, %b_eq_zero
20  %or = or i1 %and.1, %and.2
21  ret i1 %or
22}
23
24define i1 @a_or_b_not_inv(i32 %a, i32 %b){
25; CHECK-LABEL: define i1 @a_or_b_not_inv(
26; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
27; CHECK-NEXT:    [[A_EQ_ZERO:%.*]] = icmp eq i32 [[A]], 0
28; CHECK-NEXT:    [[B_NE_ZERO:%.*]] = icmp ne i32 [[B]], 0
29; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[A_EQ_ZERO]], [[B_NE_ZERO]]
30; CHECK-NEXT:    [[A_NE_ZERO:%.*]] = icmp ne i32 [[A]], 0
31; CHECK-NEXT:    [[B_EQ_1:%.*]] = icmp eq i32 [[B]], 1
32; CHECK-NEXT:    [[AND_2:%.*]] = and i1 [[A_NE_ZERO]], [[B_EQ_1]]
33; CHECK-NEXT:    [[OR:%.*]] = or i1 [[AND_1]], [[AND_2]]
34; CHECK-NEXT:    ret i1 [[OR]]
35;
36  %a_eq_zero = icmp eq i32 %a, 0
37  %b_ne_zero = icmp ne i32 %b, 0
38  %and.1 = and i1 %a_eq_zero, %b_ne_zero
39  %a_ne_zero = icmp ne i32 %a, 0
40  %b_eq_1 = icmp eq i32 %b, 1
41  %and.2 = and i1 %a_ne_zero, %b_eq_1
42  %or = or i1 %and.1, %and.2
43  ret i1 %or
44}
45
46define i1 @a_or_b_const(i32 %a, i32 %b, i32 %c)  {
47; CHECK-LABEL: define i1 @a_or_b_const(
48; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
49; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[A]], [[C]]
50; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[B]], [[C]]
51; CHECK-NEXT:    [[OR:%.*]] = xor i1 [[TMP1]], [[TMP2]]
52; CHECK-NEXT:    ret i1 [[OR]]
53;
54  %a_eq_c = icmp eq i32 %a, %c
55  %b_ne_c = icmp ne i32 %b, %c
56  %and.1 = and i1 %a_eq_c, %b_ne_c
57  %a_ne_c = icmp ne i32 %a, %c
58  %b_eq_c = icmp eq i32 %b, %c
59  %and.2 = and i1 %a_ne_c, %b_eq_c
60  %or = or i1 %and.1, %and.2
61  ret i1 %or
62}
63
64define i1 @a_or_b_const2(i32 %a, i32 %b, i32 %c, i32 %d)  {
65; CHECK-LABEL: define i1 @a_or_b_const2(
66; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
67; CHECK-NEXT:    [[A_EQ_C:%.*]] = icmp eq i32 [[A]], [[C]]
68; CHECK-NEXT:    [[B_EQ_D:%.*]] = icmp eq i32 [[B]], [[D]]
69; CHECK-NEXT:    [[OR:%.*]] = xor i1 [[A_EQ_C]], [[B_EQ_D]]
70; CHECK-NEXT:    ret i1 [[OR]]
71;
72  %a_eq_c = icmp eq i32 %a, %c
73  %b_ne_d = icmp ne i32 %b, %d
74  %and.1 = and i1 %a_eq_c, %b_ne_d
75  %a_ne_c = icmp ne i32 %a, %c
76  %b_eq_d = icmp eq i32 %b, %d
77  %and.2 = and i1 %a_ne_c, %b_eq_d
78  %or = or i1 %and.1, %and.2
79  ret i1 %or
80}
81define i1 @a_or_b_nullptr(ptr %a, ptr %b) {
82; CHECK-LABEL: define i1 @a_or_b_nullptr(
83; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]]) {
84; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[A]], null
85; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[B]], null
86; CHECK-NEXT:    [[OR:%.*]] = xor i1 [[TMP1]], [[TMP2]]
87; CHECK-NEXT:    ret i1 [[OR]]
88;
89  %a_null = icmp eq ptr %a, null
90  %b_null = icmp eq ptr %b, null
91  %a_not_null = icmp ne ptr %a, null
92  %b_not_null = icmp ne ptr %b, null
93  %and.1 = and i1 %a_null, %b_not_null
94  %and.2 = and i1 %a_not_null, %b_null
95  %or = or i1 %and.1, %and.2
96  ret i1 %or
97}
98
99define i1 @a_or_b_multiple_uses(i32 %a, i32 %b)  {
100; CHECK-LABEL: define i1 @a_or_b_multiple_uses(
101; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
102; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[A]], 0
103; CHECK-NEXT:    [[A_NE_ZERO:%.*]] = icmp ne i32 [[A]], 0
104; CHECK-NEXT:    [[B_EQ_ZERO:%.*]] = icmp eq i32 [[B]], 0
105; CHECK-NEXT:    [[AND_2:%.*]] = and i1 [[A_NE_ZERO]], [[B_EQ_ZERO]]
106; CHECK-NEXT:    call void @use(i1 [[AND_2]])
107; CHECK-NEXT:    [[OR:%.*]] = xor i1 [[TMP1]], [[B_EQ_ZERO]]
108; CHECK-NEXT:    ret i1 [[OR]]
109;
110  %a_eq_zero = icmp eq i32 %a, 0
111  %b_ne_zero = icmp ne i32 %b, 0
112  %and.1 = and i1 %a_eq_zero, %b_ne_zero
113  %a_ne_zero = icmp ne i32 %a, 0
114  %b_eq_zero = icmp eq i32 %b, 0
115  %and.2 = and i1 %a_ne_zero, %b_eq_zero
116  call void @use(i1 %and.2)
117  %or = or i1 %and.1, %and.2
118  ret i1 %or
119}
120
121define i1 @a_or_b_multiple_uses_2(i32 %a, i32 %b)  {
122; CHECK-LABEL: define i1 @a_or_b_multiple_uses_2(
123; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
124; CHECK-NEXT:    [[A_EQ_ZERO:%.*]] = icmp eq i32 [[A]], 0
125; CHECK-NEXT:    [[B_NE_ZERO:%.*]] = icmp ne i32 [[B]], 0
126; CHECK-NEXT:    call void @use(i1 [[B_NE_ZERO]])
127; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[A_EQ_ZERO]], [[B_NE_ZERO]]
128; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[B]], 0
129; CHECK-NEXT:    call void @use(i1 [[AND_1]])
130; CHECK-NEXT:    [[OR:%.*]] = xor i1 [[A_EQ_ZERO]], [[TMP1]]
131; CHECK-NEXT:    ret i1 [[OR]]
132;
133  %a_eq_zero = icmp eq i32 %a, 0
134  %b_ne_zero = icmp ne i32 %b, 0
135  call void @use(i1 %b_ne_zero)
136  %and.1 = and i1 %a_eq_zero, %b_ne_zero
137  %a_ne_zero = icmp ne i32 %a, 0
138  %b_eq_zero = icmp eq i32 %b, 0
139  %and.2 = and i1 %a_ne_zero, %b_eq_zero
140  call void @use(i1 %and.1)
141  %or = or i1 %and.1, %and.2
142  ret i1 %or
143}
144
145
146