1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s 3 4define i8 @leaf1_and_aa(i8 %a) { 5; CHECK-LABEL: @leaf1_and_aa( 6; CHECK-NEXT: [[AND_AA:%.*]] = and i8 [[A:%.*]], [[A]] 7; CHECK-NEXT: ret i8 [[AND_AA]] 8; 9 %and.aa = and i8 %a, %a 10 ret i8 %and.aa 11} 12 13define i8 @leaf1_and_a_false(i8 %a) { 14; CHECK-LABEL: @leaf1_and_a_false( 15; CHECK-NEXT: [[AND_AA:%.*]] = and i8 [[A:%.*]], 0 16; CHECK-NEXT: ret i8 [[AND_AA]] 17; 18 %and.aa = and i8 %a, 0 19 ret i8 %and.aa 20} 21 22define i8 @leaf1_xor_aa(i8 %a) { 23; CHECK-LABEL: @leaf1_xor_aa( 24; CHECK-NEXT: [[XOR_AA:%.*]] = xor i8 [[A:%.*]], [[A]] 25; CHECK-NEXT: ret i8 [[XOR_AA]] 26; 27 %xor.aa = xor i8 %a, %a 28 ret i8 %xor.aa 29} 30 31define i8 @leaf1_and_not(i8 %a) { 32; CHECK-LABEL: @leaf1_and_not( 33; CHECK-NEXT: [[NOT_A:%.*]] = xor i8 [[A:%.*]], -1 34; CHECK-NEXT: [[AND:%.*]] = and i8 [[A]], [[NOT_A]] 35; CHECK-NEXT: ret i8 [[AND]] 36; 37 %not.a = xor i8 %a, -1 38 %and = and i8 %a, %not.a 39 ret i8 %and 40} 41 42define i8 @leaf1_or_not(i8 %a) { 43; CHECK-LABEL: @leaf1_or_not( 44; CHECK-NEXT: [[NOT_A:%.*]] = xor i8 [[A:%.*]], -1 45; CHECK-NEXT: [[OR:%.*]] = or i8 [[A]], [[NOT_A]] 46; CHECK-NEXT: ret i8 [[OR]] 47; 48 %not.a = xor i8 %a, -1 49 %or = or i8 %a, %not.a 50 ret i8 %or 51} 52 53define i8 @leaf2_xor(i8 %a, i8 %b) { 54; CHECK-LABEL: @leaf2_xor( 55; CHECK-NEXT: [[AB:%.*]] = xor i8 [[A:%.*]], [[B:%.*]] 56; CHECK-NEXT: [[XOR_AB_A:%.*]] = xor i8 [[AB]], [[A]] 57; CHECK-NEXT: ret i8 [[XOR_AB_A]] 58; 59 %ab = xor i8 %a, %b 60 %xor.ab.a = xor i8 %ab, %a 61 ret i8 %xor.ab.a 62} 63 64define i8 @leaf2_xor_ret_const_false(i8 %a, i8 %b) { 65; CHECK-LABEL: @leaf2_xor_ret_const_false( 66; CHECK-NEXT: [[XOR_AB:%.*]] = xor i8 [[A:%.*]], [[B:%.*]] 67; CHECK-NEXT: [[XOR_AB_A:%.*]] = xor i8 [[XOR_AB]], [[A]] 68; CHECK-NEXT: [[XOR_AB_A_B:%.*]] = xor i8 [[XOR_AB_A]], [[B]] 69; CHECK-NEXT: ret i8 [[XOR_AB_A_B]] 70; 71 %xor.ab = xor i8 %a, %b 72 %xor.ab.a = xor i8 %xor.ab, %a 73 %xor.ab.a.b = xor i8 %xor.ab.a, %b 74 ret i8 %xor.ab.a.b 75} 76 77define i8 @leaf2_or_ret_leaf(i8 %a, i8 %b) { 78; CHECK-LABEL: @leaf2_or_ret_leaf( 79; CHECK-NEXT: [[OR_AB:%.*]] = or i8 [[A:%.*]], [[B:%.*]] 80; CHECK-NEXT: [[AND_AB:%.*]] = and i8 [[A]], [[B]] 81; CHECK-NEXT: [[XOR1:%.*]] = xor i8 [[OR_AB]], [[AND_AB]] 82; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[XOR1]], [[A]] 83; CHECK-NEXT: ret i8 [[XOR2]] 84; 85 %or.ab = or i8 %a, %b 86 %and.ab = and i8 %a, %b 87 %xor1 = xor i8 %or.ab, %and.ab 88 %xor2 = xor i8 %xor1, %a 89 ret i8 %xor2 90} 91 92define i8 @leaf2_or_ret_const_false(i8 %a, i8 %b) { 93; CHECK-LABEL: @leaf2_or_ret_const_false( 94; CHECK-NEXT: [[OR_AB:%.*]] = or i8 [[A:%.*]], [[B:%.*]] 95; CHECK-NEXT: [[AND_AB:%.*]] = and i8 [[A]], [[B]] 96; CHECK-NEXT: [[XOR1:%.*]] = xor i8 [[OR_AB]], [[AND_AB]] 97; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[XOR1]], [[A]] 98; CHECK-NEXT: [[XOR3:%.*]] = xor i8 [[XOR1]], [[B]] 99; CHECK-NEXT: ret i8 [[XOR3]] 100; 101 %or.ab = or i8 %a, %b 102 %and.ab = and i8 %a, %b 103 %xor1 = xor i8 %or.ab, %and.ab 104 %xor2 = xor i8 %xor1, %a 105 %xor3 = xor i8 %xor1, %b 106 ret i8 %xor3 107} 108 109define i1 @leaf2_type_is_i1(i1 %a, i1 %b) { 110; CHECK-LABEL: @leaf2_type_is_i1( 111; CHECK-NEXT: [[XOR_AB:%.*]] = xor i1 [[A:%.*]], [[B:%.*]] 112; CHECK-NEXT: [[NOT_A:%.*]] = xor i1 [[A]], true 113; CHECK-NEXT: [[XOR2:%.*]] = xor i1 [[NOT_A]], [[B]] 114; CHECK-NEXT: [[OR:%.*]] = or i1 [[XOR2]], [[XOR_AB]] 115; CHECK-NEXT: ret i1 [[OR]] 116; 117 %xor.ab = xor i1 %a, %b 118 %not.a = xor i1 %a, true 119 %xor2 = xor i1 %not.a, %b 120 %or = or i1 %xor2, %xor.ab 121 ret i1 %or 122} 123 124define i8 @leaf3_complex_ret_const_false(i8 %a, i8 %b, i8 %c) { 125; CHECK-LABEL: @leaf3_complex_ret_const_false( 126; CHECK-NEXT: [[AB:%.*]] = or i8 [[A:%.*]], [[B:%.*]] 127; CHECK-NEXT: [[ABC:%.*]] = or i8 [[AB]], [[C:%.*]] 128; CHECK-NEXT: [[NOT_ABC:%.*]] = xor i8 [[ABC]], -1 129; CHECK-NEXT: [[R:%.*]] = and i8 [[NOT_ABC]], [[A]] 130; CHECK-NEXT: ret i8 [[R]] 131; 132 %ab = or i8 %a, %b 133 %abc = or i8 %ab, %c 134 %not.abc = xor i8 %abc, -1 135 %r = and i8 %not.abc, %a 136 ret i8 %r 137} 138 139define i8 @leaf3_complex_ret_leaf(i8 %a, i8 %b, i8 %c) { 140; CHECK-LABEL: @leaf3_complex_ret_leaf( 141; CHECK-NEXT: [[AB:%.*]] = and i8 [[A:%.*]], [[B:%.*]] 142; CHECK-NEXT: [[BC:%.*]] = and i8 [[B]], [[C:%.*]] 143; CHECK-NEXT: [[XOR_AC:%.*]] = xor i8 [[A]], [[C]] 144; CHECK-NEXT: [[OR:%.*]] = or i8 [[AB]], [[XOR_AC]] 145; CHECK-NEXT: [[NOT_BC:%.*]] = xor i8 [[BC]], -1 146; CHECK-NEXT: [[AND:%.*]] = and i8 [[NOT_BC]], [[A]] 147; CHECK-NEXT: [[COND:%.*]] = xor i8 [[AND]], [[OR]] 148; CHECK-NEXT: ret i8 [[COND]] 149; 150 %ab = and i8 %a, %b 151 %bc = and i8 %b, %c 152 %xor.ac = xor i8 %a, %c 153 %or = or i8 %ab, %xor.ac 154 %not.bc = xor i8 %bc, -1 155 %and = and i8 %not.bc, %a 156 %cond = xor i8 %and, %or 157 ret i8 %cond 158} 159 160define i8 @leaf4_ret_const_true(i8 %a, i8 %b, i8 %c, i8 %d) { 161; CHECK-LABEL: @leaf4_ret_const_true( 162; CHECK-NEXT: [[BD:%.*]] = and i8 [[B:%.*]], [[D:%.*]] 163; CHECK-NEXT: [[NOT_BD:%.*]] = xor i8 [[BD]], -1 164; CHECK-NEXT: [[XOR_AB:%.*]] = xor i8 [[A:%.*]], [[B]] 165; CHECK-NEXT: [[OR1:%.*]] = or i8 [[XOR_AB]], [[C:%.*]] 166; CHECK-NEXT: [[OR2:%.*]] = or i8 [[OR1]], [[NOT_BD]] 167; CHECK-NEXT: [[OR3:%.*]] = or i8 [[OR2]], [[A]] 168; CHECK-NEXT: ret i8 [[OR3]] 169; 170 %bd = and i8 %b, %d 171 %not.bd = xor i8 %bd, -1 172 %xor.ab = xor i8 %a, %b 173 %or1 = or i8 %xor.ab, %c 174 %or2 = or i8 %or1, %not.bd 175 %or3 = or i8 %or2, %a 176 ret i8 %or3 177} 178 179define i8 @leaf4_ret_leaf(i8 %a, i8 %b, i8 %c, i8 %d) { 180; CHECK-LABEL: @leaf4_ret_leaf( 181; CHECK-NEXT: [[BD:%.*]] = and i8 [[B:%.*]], [[D:%.*]] 182; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[BD]], [[C:%.*]] 183; CHECK-NEXT: [[NOT_BD:%.*]] = xor i8 [[XOR]], -1 184; CHECK-NEXT: [[XOR_AB:%.*]] = xor i8 [[A:%.*]], [[B]] 185; CHECK-NEXT: [[OR1:%.*]] = or i8 [[XOR_AB]], [[C]] 186; CHECK-NEXT: [[OR2:%.*]] = or i8 [[OR1]], [[NOT_BD]] 187; CHECK-NEXT: [[OR3:%.*]] = or i8 [[OR2]], [[A]] 188; CHECK-NEXT: [[AND:%.*]] = and i8 [[OR3]], [[B]] 189; CHECK-NEXT: ret i8 [[AND]] 190; 191 %bd = and i8 %b, %d 192 %xor = xor i8 %bd, %c 193 %not.bd = xor i8 %xor, -1 194 %xor.ab = xor i8 %a, %b 195 %or1 = or i8 %xor.ab, %c 196 %or2 = or i8 %or1, %not.bd 197 %or3 = or i8 %or2, %a 198 %and = and i8 %or3, %b 199 ret i8 %and 200} 201 202define i8 @leaf4_ret_leaf2(i8 %a, i8 %b, i8 %c, i8 %d) { 203; CHECK-LABEL: @leaf4_ret_leaf2( 204; CHECK-NEXT: [[BD:%.*]] = and i8 [[B:%.*]], [[D:%.*]] 205; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[BD]], [[C:%.*]] 206; CHECK-NEXT: [[NOT_BD:%.*]] = xor i8 [[XOR]], -1 207; CHECK-NEXT: [[XOR_AB:%.*]] = xor i8 [[A:%.*]], [[B]] 208; CHECK-NEXT: [[OR1:%.*]] = or i8 [[XOR_AB]], [[C]] 209; CHECK-NEXT: [[OR2:%.*]] = or i8 [[OR1]], [[NOT_BD]] 210; CHECK-NEXT: [[OR3:%.*]] = or i8 [[OR2]], [[A]] 211; CHECK-NEXT: [[AND:%.*]] = and i8 [[OR3]], [[B]] 212; CHECK-NEXT: ret i8 [[AND]] 213; 214 %bd = and i8 %b, %d 215 %xor = xor i8 %bd, %c 216 %not.bd = xor i8 %xor, -1 217 %xor.ab = xor i8 %a, %b 218 %or1 = or i8 %xor.ab, %c 219 %or2 = or i8 %or1, %not.bd 220 %or3 = or i8 %or2, %a 221 %and = and i8 %or3, %b 222 ret i8 %and 223} 224