1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s 3 4define i32 @poison(i32 %x) { 5; CHECK-LABEL: @poison( 6; CHECK-NEXT: ret i32 poison 7; 8 %v = and i32 %x, poison 9 ret i32 %v 10} 11 12; (X | Y) & (X | ~Y) --> X (commuted 8 ways) 13 14define i8 @or_or_not_commute0(i8 %x, i8 %y) { 15; CHECK-LABEL: @or_or_not_commute0( 16; CHECK-NEXT: ret i8 [[X:%.*]] 17; 18 %ynot = xor i8 %y, -1 19 %xory = or i8 %x, %y 20 %xorynot = or i8 %x, %ynot 21 %and = and i8 %xory, %xorynot 22 ret i8 %and 23} 24 25define <2 x i5> @or_or_not_commute1(<2 x i5> %x, <2 x i5> %y) { 26; CHECK-LABEL: @or_or_not_commute1( 27; CHECK-NEXT: ret <2 x i5> [[X:%.*]] 28; 29 %ynot = xor <2 x i5> %y, <i5 -1, i5 -1> 30 %xory = or <2 x i5> %x, %y 31 %xorynot = or <2 x i5> %x, %ynot 32 %and = and <2 x i5> %xorynot, %xory 33 ret <2 x i5> %and 34} 35 36define <2 x i8> @or_or_not_commute2(<2 x i8> %x, <2 x i8> %y) { 37; CHECK-LABEL: @or_or_not_commute2( 38; CHECK-NEXT: ret <2 x i8> [[X:%.*]] 39; 40 %ynot = xor <2 x i8> %y, <i8 poison, i8 -1> 41 %xory = or <2 x i8> %x, %y 42 %xorynot = or <2 x i8> %ynot, %x 43 %and = and <2 x i8> %xory, %xorynot 44 ret <2 x i8> %and 45} 46 47define i8 @or_or_not_commute3(i8 %x, i8 %y) { 48; CHECK-LABEL: @or_or_not_commute3( 49; CHECK-NEXT: ret i8 [[X:%.*]] 50; 51 %ynot = xor i8 %y, -1 52 %xory = or i8 %x, %y 53 %xorynot = or i8 %ynot, %x 54 %and = and i8 %xorynot, %xory 55 ret i8 %and 56} 57define i8 @or_or_not_commute4(i8 %x, i8 %y) { 58; CHECK-LABEL: @or_or_not_commute4( 59; CHECK-NEXT: ret i8 [[X:%.*]] 60; 61 %ynot = xor i8 %y, -1 62 %xory = or i8 %y, %x 63 %xorynot = or i8 %x, %ynot 64 %and = and i8 %xory, %xorynot 65 ret i8 %and 66} 67 68define i8 @or_or_not_commute5(i8 %x, i8 %y) { 69; CHECK-LABEL: @or_or_not_commute5( 70; CHECK-NEXT: ret i8 [[X:%.*]] 71; 72 %ynot = xor i8 %y, -1 73 %xory = or i8 %y, %x 74 %xorynot = or i8 %x, %ynot 75 %and = and i8 %xorynot, %xory 76 ret i8 %and 77} 78 79define i8 @or_or_not_commute6(i8 %x, i8 %y) { 80; CHECK-LABEL: @or_or_not_commute6( 81; CHECK-NEXT: ret i8 [[X:%.*]] 82; 83 %ynot = xor i8 %y, -1 84 %xory = or i8 %y, %x 85 %xorynot = or i8 %ynot, %x 86 %and = and i8 %xory, %xorynot 87 ret i8 %and 88} 89 90define i8 @or_or_not_commute7(i8 %x, i8 %y) { 91; CHECK-LABEL: @or_or_not_commute7( 92; CHECK-NEXT: ret i8 [[X:%.*]] 93; 94 %ynot = xor i8 %y, -1 95 %xory = or i8 %y, %x 96 %xorynot = or i8 %ynot, %x 97 %and = and i8 %xorynot, %xory 98 ret i8 %and 99} 100 101; negative test - wrong logic op 102 103define i8 @or_xor_not(i8 %x, i8 %y) { 104; CHECK-LABEL: @or_xor_not( 105; CHECK-NEXT: [[YNOT:%.*]] = xor i8 [[Y:%.*]], -1 106; CHECK-NEXT: [[XXORY:%.*]] = xor i8 [[Y]], [[X:%.*]] 107; CHECK-NEXT: [[XORYNOT:%.*]] = or i8 [[X]], [[YNOT]] 108; CHECK-NEXT: [[AND:%.*]] = and i8 [[XORYNOT]], [[XXORY]] 109; CHECK-NEXT: ret i8 [[AND]] 110; 111 %ynot = xor i8 %y, -1 112 %xxory = xor i8 %y, %x 113 %xorynot = or i8 %x, %ynot 114 %and = and i8 %xorynot, %xxory 115 ret i8 %and 116} 117 118; negative test - must have common operands 119 120define i8 @or_or_not_no_common_op(i8 %x, i8 %y, i8 %z) { 121; CHECK-LABEL: @or_or_not_no_common_op( 122; CHECK-NEXT: [[XORZ:%.*]] = or i8 [[Z:%.*]], [[X:%.*]] 123; CHECK-NEXT: [[YNOT:%.*]] = xor i8 [[Y:%.*]], -1 124; CHECK-NEXT: [[XORYNOT:%.*]] = or i8 [[X]], [[YNOT]] 125; CHECK-NEXT: [[AND:%.*]] = and i8 [[XORYNOT]], [[XORZ]] 126; CHECK-NEXT: ret i8 [[AND]] 127; 128 %xorz = or i8 %z, %x 129 %ynot = xor i8 %y, -1 130 %xorynot = or i8 %x, %ynot 131 %and = and i8 %xorynot, %xorz 132 ret i8 %and 133} 134 135; ((X | Y) ^ X ) & ((X | Y) ^ Y) --> 0 136 137define i8 @or_xor(i8 %x, i8 %y) { 138; CHECK-LABEL: @or_xor( 139; CHECK-NEXT: ret i8 0 140; 141 %or = or i8 %x, %y 142 %xor1 = xor i8 %or, %x 143 %xor2 = xor i8 %or, %y 144 %and = and i8 %xor1, %xor2 145 ret i8 %and 146} 147 148; ((X | Y) ^ Y ) & ((X | Y) ^ X) --> 0 149 150define i8 @or_xor_commute1(i8 %x, i8 %y) { 151; CHECK-LABEL: @or_xor_commute1( 152; CHECK-NEXT: ret i8 0 153; 154 %or = or i8 %x, %y 155 %xor1 = xor i8 %or, %x 156 %xor2 = xor i8 %or, %y 157 %and = and i8 %xor2, %xor1 158 ret i8 %and 159} 160 161; (X ^ (X | Y) ) & (Y ^ (X | Y)) --> 0 162 163define i71 @or_xor_commute2(i71 %x, i71 %y) { 164; CHECK-LABEL: @or_xor_commute2( 165; CHECK-NEXT: ret i71 0 166; 167 %or = or i71 %x, %y 168 %xor1 = xor i71 %x, %or 169 %xor2 = xor i71 %y, %or 170 %and = and i71 %xor1, %xor2 171 ret i71 %and 172} 173 174; (Y ^ (X | Y) ) & (X ^ (X | Y)) --> 0 175 176define <2 x i64> @or_xor_commute3(<2 x i64> %x, <2 x i64> %y) { 177; CHECK-LABEL: @or_xor_commute3( 178; CHECK-NEXT: ret <2 x i64> zeroinitializer 179; 180 %or = or <2 x i64> %x, %y 181 %xor1 = xor <2 x i64> %y, %or 182 %xor2 = xor <2 x i64> %x, %or 183 %and = and <2 x i64> %xor1, %xor2 184 ret <2 x i64> %and 185} 186 187; ((X | Y) ^ X ) & (Y ^ (X | Y)) --> 0 188 189define i32 @or_xor_commute4(i32 %x, i32 %y) { 190; CHECK-LABEL: @or_xor_commute4( 191; CHECK-NEXT: ret i32 0 192; 193 %or = or i32 %x, %y 194 %xor1 = xor i32 %or, %x 195 %xor2 = xor i32 %y, %or 196 %and = and i32 %xor1, %xor2 197 ret i32 %and 198} 199 200; ((X | Y) ^ Y ) & (X ^ (X | Y)) --> 0 201 202define i32 @or_xor_commute5(i32 %x, i32 %y) { 203; CHECK-LABEL: @or_xor_commute5( 204; CHECK-NEXT: ret i32 0 205; 206 %or = or i32 %x, %y 207 %xor1 = xor i32 %or, %y 208 %xor2 = xor i32 %x, %or 209 %and = and i32 %xor1, %xor2 210 ret i32 %and 211} 212 213; (X ^ (X | Y) ) & ((X | Y) ^ Y) --> 0 214 215define i32 @or_xor_commute6(i32 %x, i32 %y) { 216; CHECK-LABEL: @or_xor_commute6( 217; CHECK-NEXT: ret i32 0 218; 219 %or = or i32 %x, %y 220 %xor1 = xor i32 %x, %or 221 %xor2 = xor i32 %or, %y 222 %and = and i32 %xor1, %xor2 223 ret i32 %and 224} 225 226; (Y ^ (X | Y) ) & ((X | Y) ^ X) --> 0 227 228define i32 @or_xor_commute7(i32 %x, i32 %y) { 229; CHECK-LABEL: @or_xor_commute7( 230; CHECK-NEXT: ret i32 0 231; 232 %or = or i32 %x, %y 233 %xor1 = xor i32 %y, %or 234 %xor2 = xor i32 %or, %x 235 %and = and i32 %xor1, %xor2 236 ret i32 %and 237} 238 239; (Y ^ (X | Y) ) & ((X | Y) ^ X) --> 0 240 241define i32 @or_xor_complex_op(i32 %x, i32 %in) { 242; CHECK-LABEL: @or_xor_complex_op( 243; CHECK-NEXT: ret i32 0 244; 245 %y = or i32 %in, 1 246 %or = or i32 %x, %y 247 %xor1 = xor i32 %y, %or 248 %xor2 = xor i32 %or, %x 249 %and = and i32 %xor1, %xor2 250 ret i32 %and 251} 252 253define i32 @or_xor_limitation(i32 %x, i32 %y) { 254; CHECK-LABEL: @or_xor_limitation( 255; CHECK-NEXT: [[OR1:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 256; CHECK-NEXT: [[OR2:%.*]] = or i32 [[X]], [[Y]] 257; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[Y]], [[OR1]] 258; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[OR2]], [[X]] 259; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]] 260; CHECK-NEXT: ret i32 [[AND]] 261; 262 %or1 = or i32 %y, %x 263 %or2 = or i32 %x, %y 264 %xor1 = xor i32 %y, %or1 265 %xor2 = xor i32 %or2, %x 266 %and = and i32 %xor1, %xor2 267 ret i32 %and 268} 269