1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4declare void @use(i32) 5declare void @use_i8(i8) 6declare void @use_i1(i1) 7 8; a & (a ^ b) --> a & ~b 9 10define i32 @and_xor_common_op(i32 %pa, i32 %pb) { 11; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op 12; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) { 13; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[PA]] 14; CHECK-NEXT: [[B:%.*]] = udiv i32 43, [[PB]] 15; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 16; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], [[TMP1]] 17; CHECK-NEXT: ret i32 [[R]] 18; 19 %a = udiv i32 42, %pa ; thwart complexity-based canonicalization 20 %b = udiv i32 43, %pb ; thwart complexity-based canonicalization 21 %xor = xor i32 %a, %b 22 %r = and i32 %a, %xor 23 ret i32 %r 24} 25 26; a & (b ^ a) --> a & ~b 27 28define i32 @and_xor_common_op_commute1(i32 %pa, i32 %pb) { 29; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op_commute1 30; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) { 31; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[PA]] 32; CHECK-NEXT: [[B:%.*]] = udiv i32 43, [[PB]] 33; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 34; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], [[TMP1]] 35; CHECK-NEXT: ret i32 [[R]] 36; 37 %a = udiv i32 42, %pa ; thwart complexity-based canonicalization 38 %b = udiv i32 43, %pb ; thwart complexity-based canonicalization 39 %xor = xor i32 %b, %a 40 %r = and i32 %a, %xor 41 ret i32 %r 42} 43 44; (b ^ a) & a --> a & ~b 45 46define i32 @and_xor_common_op_commute2(i32 %pa, i32 %pb) { 47; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op_commute2 48; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) { 49; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[PA]] 50; CHECK-NEXT: [[B:%.*]] = udiv i32 43, [[PB]] 51; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 52; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], [[TMP1]] 53; CHECK-NEXT: ret i32 [[R]] 54; 55 %a = udiv i32 42, %pa ; thwart complexity-based canonicalization 56 %b = udiv i32 43, %pb ; thwart complexity-based canonicalization 57 %xor = xor i32 %b, %a 58 %r = and i32 %xor, %a 59 ret i32 %r 60} 61 62; (a ^ b) & a --> a & ~b 63 64define <2 x i32> @and_xor_common_op_commute3(<2 x i32> %pa, <2 x i32> %pb) { 65; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op_commute3 66; CHECK-SAME: (<2 x i32> [[PA:%.*]], <2 x i32> [[PB:%.*]]) { 67; CHECK-NEXT: [[A:%.*]] = udiv <2 x i32> <i32 42, i32 43>, [[PA]] 68; CHECK-NEXT: [[B:%.*]] = udiv <2 x i32> <i32 43, i32 42>, [[PB]] 69; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[B]], splat (i32 -1) 70; CHECK-NEXT: [[R:%.*]] = and <2 x i32> [[A]], [[TMP1]] 71; CHECK-NEXT: ret <2 x i32> [[R]] 72; 73 %a = udiv <2 x i32> <i32 42, i32 43>, %pa ; thwart complexity-based canonicalization 74 %b = udiv <2 x i32> <i32 43, i32 42>, %pb ; thwart complexity-based canonicalization 75 %xor = xor <2 x i32> %a, %b 76 %r = and <2 x i32> %xor, %a 77 ret <2 x i32> %r 78} 79 80; It's ok to match a common constant. 81; The xor should be a 'not' op (-1 constant). 82 83define <4 x i32> @and_xor_common_op_constant(<4 x i32> %A) { 84; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op_constant 85; CHECK-SAME: (<4 x i32> [[A:%.*]]) { 86; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i32> [[A]], splat (i32 -1) 87; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i32> [[TMP1]], <i32 1, i32 2, i32 3, i32 4> 88; CHECK-NEXT: ret <4 x i32> [[TMP2]] 89; 90 %1 = xor <4 x i32> %A, <i32 1, i32 2, i32 3, i32 4> 91 %2 = and <4 x i32> <i32 1, i32 2, i32 3, i32 4>, %1 92 ret <4 x i32> %2 93} 94 95; a & (a ^ ~b) --> a & b 96 97define i32 @and_xor_not_common_op(i32 %a, i32 %b) { 98; CHECK-LABEL: define {{[^@]+}}@and_xor_not_common_op 99; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) { 100; CHECK-NEXT: [[T4:%.*]] = and i32 [[A]], [[B]] 101; CHECK-NEXT: ret i32 [[T4]] 102; 103 %b2 = xor i32 %b, -1 104 %t2 = xor i32 %a, %b2 105 %t4 = and i32 %t2, %a 106 ret i32 %t4 107} 108 109; a & (a ^ ~b) --> a & b 110 111define i32 @and_xor_not_common_op_extrause(i32 %a, i32 %b, ptr %dst) { 112; CHECK-LABEL: define {{[^@]+}}@and_xor_not_common_op_extrause 113; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], ptr [[DST:%.*]]) { 114; CHECK-NEXT: [[B2:%.*]] = xor i32 [[B]], -1 115; CHECK-NEXT: store i32 [[B2]], ptr [[DST]], align 4 116; CHECK-NEXT: [[T4:%.*]] = and i32 [[B]], [[A]] 117; CHECK-NEXT: ret i32 [[T4]] 118; 119 %b2 = xor i32 %b, -1 120 store i32 %b2, ptr %dst 121 %t2 = xor i32 %a, %b2 122 %t4 = and i32 %t2, %a 123 ret i32 %t4 124} 125 126; a & ~(a ^ b) --> a & b 127 128define i32 @and_not_xor_common_op(i32 %a, i32 %b) { 129; CHECK-LABEL: define {{[^@]+}}@and_not_xor_common_op 130; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) { 131; CHECK-NEXT: [[T4:%.*]] = and i32 [[A]], [[B]] 132; CHECK-NEXT: ret i32 [[T4]] 133; 134 %b2 = xor i32 %b, %a 135 %t2 = xor i32 %b2, -1 136 %t4 = and i32 %t2, %a 137 ret i32 %t4 138} 139 140declare i32 @gen32() 141define i32 @and_not_xor_common_op_commutative(i32 %b) { 142; CHECK-LABEL: define {{[^@]+}}@and_not_xor_common_op_commutative 143; CHECK-SAME: (i32 [[B:%.*]]) { 144; CHECK-NEXT: [[A:%.*]] = call i32 @gen32() 145; CHECK-NEXT: [[T4:%.*]] = and i32 [[A]], [[B]] 146; CHECK-NEXT: ret i32 [[T4]] 147; 148 %a = call i32 @gen32() 149 %b2 = xor i32 %a, %b ; swapped order 150 %t2 = xor i32 %b2, -1 151 %t4 = and i32 %a, %t2 ; swapped order 152 ret i32 %t4 153} 154 155; rdar://10770603 156; (x & y) | (x ^ y) -> x | y 157 158define i64 @or(i64 %x, i64 %y) { 159; CHECK-LABEL: define {{[^@]+}}@or 160; CHECK-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) { 161; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y]], [[X]] 162; CHECK-NEXT: ret i64 [[TMP1]] 163; 164 %1 = and i64 %y, %x 165 %2 = xor i64 %y, %x 166 %3 = add i64 %1, %2 167 ret i64 %3 168} 169 170; (x & y) + (x ^ y) -> x | y 171 172define i64 @or2(i64 %x, i64 %y) { 173; CHECK-LABEL: define {{[^@]+}}@or2 174; CHECK-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) { 175; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y]], [[X]] 176; CHECK-NEXT: ret i64 [[TMP1]] 177; 178 %1 = and i64 %y, %x 179 %2 = xor i64 %y, %x 180 %3 = or i64 %1, %2 181 ret i64 %3 182} 183 184; ((x & y) ^ z) | y -> (z | y) 185 186define i64 @and_xor_or1(i64 %px, i64 %py, i64 %pz) { 187; CHECK-LABEL: define {{[^@]+}}@and_xor_or1 188; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) { 189; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]] 190; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]] 191; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Z]], [[Y]] 192; CHECK-NEXT: ret i64 [[TMP1]] 193; 194 %x = udiv i64 42, %px ; thwart complexity-based canonicalization 195 %y = udiv i64 42, %py ; thwart complexity-based canonicalization 196 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization 197 %1 = and i64 %x, %y 198 %2 = xor i64 %1, %z 199 %3 = or i64 %2, %y 200 ret i64 %3 201} 202 203; ((y & x) ^ z) | y -> (z | y) 204 205define i64 @and_xor_or2(i64 %px, i64 %py, i64 %pz) { 206; CHECK-LABEL: define {{[^@]+}}@and_xor_or2 207; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) { 208; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]] 209; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]] 210; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Z]], [[Y]] 211; CHECK-NEXT: ret i64 [[TMP1]] 212; 213 %x = udiv i64 42, %px ; thwart complexity-based canonicalization 214 %y = udiv i64 42, %py ; thwart complexity-based canonicalization 215 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization 216 %1 = and i64 %y, %x 217 %2 = xor i64 %1, %z 218 %3 = or i64 %2, %y 219 ret i64 %3 220} 221 222; (z ^ (x & y)) | y -> (z | y) 223 224define i64 @and_xor_or3(i64 %px, i64 %py, i64 %pz) { 225; CHECK-LABEL: define {{[^@]+}}@and_xor_or3 226; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) { 227; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]] 228; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]] 229; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Z]], [[Y]] 230; CHECK-NEXT: ret i64 [[TMP1]] 231; 232 %x = udiv i64 42, %px ; thwart complexity-based canonicalization 233 %y = udiv i64 42, %py ; thwart complexity-based canonicalization 234 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization 235 %1 = and i64 %x, %y 236 %2 = xor i64 %z, %1 237 %3 = or i64 %2, %y 238 ret i64 %3 239} 240 241; (z ^ (y & x)) | y -> (z | y) 242 243define i64 @and_xor_or4(i64 %px, i64 %py, i64 %pz) { 244; CHECK-LABEL: define {{[^@]+}}@and_xor_or4 245; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) { 246; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]] 247; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]] 248; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Z]], [[Y]] 249; CHECK-NEXT: ret i64 [[TMP1]] 250; 251 %x = udiv i64 42, %px ; thwart complexity-based canonicalization 252 %y = udiv i64 42, %py ; thwart complexity-based canonicalization 253 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization 254 %1 = and i64 %y, %x 255 %2 = xor i64 %z, %1 256 %3 = or i64 %2, %y 257 ret i64 %3 258} 259 260; y | ((x & y) ^ z) -> (y | z) 261 262define i64 @and_xor_or5(i64 %px, i64 %py, i64 %pz) { 263; CHECK-LABEL: define {{[^@]+}}@and_xor_or5 264; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) { 265; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]] 266; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]] 267; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y]], [[Z]] 268; CHECK-NEXT: ret i64 [[TMP1]] 269; 270 %x = udiv i64 42, %px ; thwart complexity-based canonicalization 271 %y = udiv i64 42, %py ; thwart complexity-based canonicalization 272 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization 273 %1 = and i64 %x, %y 274 %2 = xor i64 %1, %z 275 %3 = or i64 %y, %2 276 ret i64 %3 277} 278 279; y | ((y & x) ^ z) -> (y | z) 280 281define i64 @and_xor_or6(i64 %px, i64 %py, i64 %pz) { 282; CHECK-LABEL: define {{[^@]+}}@and_xor_or6 283; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) { 284; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]] 285; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]] 286; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y]], [[Z]] 287; CHECK-NEXT: ret i64 [[TMP1]] 288; 289 %x = udiv i64 42, %px ; thwart complexity-based canonicalization 290 %y = udiv i64 42, %py ; thwart complexity-based canonicalization 291 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization 292 %1 = and i64 %y, %x 293 %2 = xor i64 %1, %z 294 %3 = or i64 %y, %2 295 ret i64 %3 296} 297 298; y | (z ^ (x & y)) -> (y | z) 299 300define i64 @and_xor_or7(i64 %px, i64 %py, i64 %pz) { 301; CHECK-LABEL: define {{[^@]+}}@and_xor_or7 302; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) { 303; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]] 304; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]] 305; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y]], [[Z]] 306; CHECK-NEXT: ret i64 [[TMP1]] 307; 308 %x = udiv i64 42, %px ; thwart complexity-based canonicalization 309 %y = udiv i64 42, %py ; thwart complexity-based canonicalization 310 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization 311 %1 = and i64 %x, %y 312 %2 = xor i64 %z, %1 313 %3 = or i64 %y, %2 314 ret i64 %3 315} 316 317; y | (z ^ (y & x)) -> (y | z) 318 319define i64 @and_xor_or8(i64 %px, i64 %py, i64 %pz) { 320; CHECK-LABEL: define {{[^@]+}}@and_xor_or8 321; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) { 322; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]] 323; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]] 324; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y]], [[Z]] 325; CHECK-NEXT: ret i64 [[TMP1]] 326; 327 %x = udiv i64 42, %px ; thwart complexity-based canonicalization 328 %y = udiv i64 42, %py ; thwart complexity-based canonicalization 329 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization 330 %1 = and i64 %y, %x 331 %2 = xor i64 %z, %1 332 %3 = or i64 %y, %2 333 ret i64 %3 334} 335 336; w | (z ^ (y & x)) 337 338define i64 @and_xor_or_negative(i64 %x, i64 %y, i64 %z, i64 %w) { 339; CHECK-LABEL: define {{[^@]+}}@and_xor_or_negative 340; CHECK-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]], i64 [[W:%.*]]) { 341; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[Y]], [[X]] 342; CHECK-NEXT: [[TMP2:%.*]] = xor i64 [[Z]], [[TMP1]] 343; CHECK-NEXT: [[TMP3:%.*]] = or i64 [[W]], [[TMP2]] 344; CHECK-NEXT: ret i64 [[TMP3]] 345; 346 %1 = and i64 %y, %x 347 %2 = xor i64 %z, %1 348 %3 = or i64 %w, %2 349 ret i64 %3 350} 351 352; PR37098 - https://bugs.llvm.org/show_bug.cgi?id=37098 353; Reassociate bitwise logic to eliminate a shift. 354; There are 4 commuted * 3 shift ops * 3 logic ops = 36 potential variations of this fold. 355; Mix the commutation options to provide coverage using less tests. 356 357define i8 @and_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) { 358; CHECK-LABEL: define {{[^@]+}}@and_shl 359; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) { 360; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], [[Y]] 361; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], [[SHAMT]] 362; CHECK-NEXT: [[R:%.*]] = and i8 [[TMP2]], [[Z]] 363; CHECK-NEXT: ret i8 [[R]] 364; 365 %sx = shl i8 %x, %shamt 366 %sy = shl i8 %y, %shamt 367 %a = and i8 %sx, %z 368 %r = and i8 %sy, %a 369 ret i8 %r 370} 371 372define i8 @or_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) { 373; CHECK-LABEL: define {{[^@]+}}@or_shl 374; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) { 375; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X]], [[Y]] 376; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], [[SHAMT]] 377; CHECK-NEXT: [[R:%.*]] = or i8 [[TMP2]], [[Z]] 378; CHECK-NEXT: ret i8 [[R]] 379; 380 %sx = shl i8 %x, %shamt 381 %sy = shl i8 %y, %shamt 382 %a = or i8 %sx, %z 383 %r = or i8 %a, %sy 384 ret i8 %r 385} 386 387define i8 @xor_shl(i8 %x, i8 %y, i8 %zarg, i8 %shamt) { 388; CHECK-LABEL: define {{[^@]+}}@xor_shl 389; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) { 390; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG]] 391; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], [[Y]] 392; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], [[SHAMT]] 393; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP2]], [[Z]] 394; CHECK-NEXT: ret i8 [[R]] 395; 396 %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization 397 %sx = shl i8 %x, %shamt 398 %sy = shl i8 %y, %shamt 399 %a = xor i8 %z, %sx 400 %r = xor i8 %a, %sy 401 ret i8 %r 402} 403 404define i8 @and_lshr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) { 405; CHECK-LABEL: define {{[^@]+}}@and_lshr 406; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) { 407; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG]] 408; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], [[Y]] 409; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]] 410; CHECK-NEXT: [[R:%.*]] = and i8 [[TMP2]], [[Z]] 411; CHECK-NEXT: ret i8 [[R]] 412; 413 %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization 414 %sx = lshr i8 %x, %shamt 415 %sy = lshr i8 %y, %shamt 416 %a = and i8 %z, %sx 417 %r = and i8 %sy, %a 418 ret i8 %r 419} 420 421define i8 @or_lshr(i8 %x, i8 %y, i8 %z, i8 %shamt) { 422; CHECK-LABEL: define {{[^@]+}}@or_lshr 423; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) { 424; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X]], [[Y]] 425; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]] 426; CHECK-NEXT: [[R:%.*]] = or i8 [[TMP2]], [[Z]] 427; CHECK-NEXT: ret i8 [[R]] 428; 429 %sx = lshr i8 %x, %shamt 430 %sy = lshr i8 %y, %shamt 431 %a = or i8 %sx, %z 432 %r = or i8 %sy, %a 433 ret i8 %r 434} 435 436define i8 @or_lshr_commuted1(i8 %x, i8 %y, i8 %z, i8 %shamt) { 437; CHECK-LABEL: define {{[^@]+}}@or_lshr_commuted1 438; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) { 439; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X]], [[Y]] 440; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]] 441; CHECK-NEXT: [[R:%.*]] = or i8 [[TMP2]], [[Z]] 442; CHECK-NEXT: ret i8 [[R]] 443; 444 %sx = lshr i8 %x, %shamt 445 %sy = lshr i8 %y, %shamt 446 %a = or i8 %z, %sx 447 %r = or i8 %sy, %a 448 ret i8 %r 449} 450 451define i8 @or_lshr_commuted2(i8 %x, i8 %y, i8 %z, i8 %shamt) { 452; CHECK-LABEL: define {{[^@]+}}@or_lshr_commuted2 453; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) { 454; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X]], [[Y]] 455; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]] 456; CHECK-NEXT: [[R:%.*]] = or i8 [[TMP2]], [[Z]] 457; CHECK-NEXT: ret i8 [[R]] 458; 459 %sx = lshr i8 %x, %shamt 460 %sy = lshr i8 %y, %shamt 461 %a = or i8 %z, %sx 462 %r = or i8 %a, %sy 463 ret i8 %r 464} 465 466define i8 @or_lshr_commuted3(i8 %x, i8 %y, i8 %z, i8 %shamt) { 467; CHECK-LABEL: define {{[^@]+}}@or_lshr_commuted3 468; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) { 469; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X]], [[Y]] 470; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]] 471; CHECK-NEXT: [[R:%.*]] = or i8 [[TMP2]], [[Z]] 472; CHECK-NEXT: ret i8 [[R]] 473; 474 %sx = lshr i8 %x, %shamt 475 %sy = lshr i8 %y, %shamt 476 %a = or i8 %sx, %z 477 %r = or i8 %a, %sy 478 ret i8 %r 479} 480 481define i8 @xor_lshr(i8 %x, i8 %y, i8 %z, i8 %shamt) { 482; CHECK-LABEL: define {{[^@]+}}@xor_lshr 483; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) { 484; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], [[Y]] 485; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]] 486; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP2]], [[Z]] 487; CHECK-NEXT: ret i8 [[R]] 488; 489 %sx = lshr i8 %x, %shamt 490 %sy = lshr i8 %y, %shamt 491 %a = xor i8 %sx, %z 492 %r = xor i8 %a, %sy 493 ret i8 %r 494} 495 496define i8 @and_ashr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) { 497; CHECK-LABEL: define {{[^@]+}}@and_ashr 498; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) { 499; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG]] 500; CHECK-NEXT: [[SX:%.*]] = ashr i8 [[X]], [[SHAMT]] 501; CHECK-NEXT: [[SY:%.*]] = ashr i8 [[Y]], [[SHAMT]] 502; CHECK-NEXT: [[A:%.*]] = and i8 [[Z]], [[SX]] 503; CHECK-NEXT: [[R:%.*]] = and i8 [[A]], [[SY]] 504; CHECK-NEXT: ret i8 [[R]] 505; 506 %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization 507 %sx = ashr i8 %x, %shamt 508 %sy = ashr i8 %y, %shamt 509 %a = and i8 %z, %sx 510 %r = and i8 %a, %sy 511 ret i8 %r 512} 513 514define i8 @or_ashr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) { 515; CHECK-LABEL: define {{[^@]+}}@or_ashr 516; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) { 517; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG]] 518; CHECK-NEXT: [[SX:%.*]] = ashr i8 [[X]], [[SHAMT]] 519; CHECK-NEXT: [[SY:%.*]] = ashr i8 [[Y]], [[SHAMT]] 520; CHECK-NEXT: [[A:%.*]] = or i8 [[Z]], [[SX]] 521; CHECK-NEXT: [[R:%.*]] = or i8 [[SY]], [[A]] 522; CHECK-NEXT: ret i8 [[R]] 523; 524 %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization 525 %sx = ashr i8 %x, %shamt 526 %sy = ashr i8 %y, %shamt 527 %a = or i8 %z, %sx 528 %r = or i8 %sy, %a 529 ret i8 %r 530} 531 532define <2 x i8> @xor_ashr(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z, <2 x i8> %shamt) { 533; CHECK-LABEL: define {{[^@]+}}@xor_ashr 534; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <2 x i8> [[Z:%.*]], <2 x i8> [[SHAMT:%.*]]) { 535; CHECK-NEXT: [[SX:%.*]] = ashr <2 x i8> [[X]], [[SHAMT]] 536; CHECK-NEXT: [[SY:%.*]] = ashr <2 x i8> [[Y]], [[SHAMT]] 537; CHECK-NEXT: [[A:%.*]] = xor <2 x i8> [[SX]], [[Z]] 538; CHECK-NEXT: [[R:%.*]] = xor <2 x i8> [[A]], [[SY]] 539; CHECK-NEXT: ret <2 x i8> [[R]] 540; 541 %sx = ashr <2 x i8> %x, %shamt 542 %sy = ashr <2 x i8> %y, %shamt 543 %a = xor <2 x i8> %sx, %z 544 %r = xor <2 x i8> %a, %sy 545 ret <2 x i8> %r 546} 547 548; Negative test - different logic ops 549 550define i8 @or_and_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) { 551; CHECK-LABEL: define {{[^@]+}}@or_and_shl 552; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) { 553; CHECK-NEXT: [[SX:%.*]] = shl i8 [[X]], [[SHAMT]] 554; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y]], [[SHAMT]] 555; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z]] 556; CHECK-NEXT: [[R:%.*]] = and i8 [[SY]], [[A]] 557; CHECK-NEXT: ret i8 [[R]] 558; 559 %sx = shl i8 %x, %shamt 560 %sy = shl i8 %y, %shamt 561 %a = or i8 %sx, %z 562 %r = and i8 %sy, %a 563 ret i8 %r 564} 565 566; Negative test - different shift ops 567 568define i8 @or_lshr_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) { 569; CHECK-LABEL: define {{[^@]+}}@or_lshr_shl 570; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) { 571; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X]], [[SHAMT]] 572; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y]], [[SHAMT]] 573; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z]] 574; CHECK-NEXT: [[R:%.*]] = or i8 [[A]], [[SY]] 575; CHECK-NEXT: ret i8 [[R]] 576; 577 %sx = lshr i8 %x, %shamt 578 %sy = shl i8 %y, %shamt 579 %a = or i8 %sx, %z 580 %r = or i8 %a, %sy 581 ret i8 %r 582} 583 584; Negative test - different shift amounts 585 586define i8 @or_lshr_shamt2(i8 %x, i8 %y, i8 %z, i8 %shamt) { 587; CHECK-LABEL: define {{[^@]+}}@or_lshr_shamt2 588; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) { 589; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X]], 5 590; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y]], [[SHAMT]] 591; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z]] 592; CHECK-NEXT: [[R:%.*]] = or i8 [[SY]], [[A]] 593; CHECK-NEXT: ret i8 [[R]] 594; 595 %sx = lshr i8 %x, 5 596 %sy = lshr i8 %y, %shamt 597 %a = or i8 %sx, %z 598 %r = or i8 %sy, %a 599 ret i8 %r 600} 601 602; Negative test - multi-use 603 604define i8 @xor_lshr_multiuse(i8 %x, i8 %y, i8 %z, i8 %shamt) { 605; CHECK-LABEL: define {{[^@]+}}@xor_lshr_multiuse 606; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) { 607; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X]], [[SHAMT]] 608; CHECK-NEXT: [[A:%.*]] = xor i8 [[SX]], [[Z]] 609; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], [[Y]] 610; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]] 611; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP2]], [[Z]] 612; CHECK-NEXT: [[R2:%.*]] = sdiv i8 [[A]], [[R]] 613; CHECK-NEXT: ret i8 [[R2]] 614; 615 %sx = lshr i8 %x, %shamt 616 %sy = lshr i8 %y, %shamt 617 %a = xor i8 %sx, %z 618 %r = xor i8 %a, %sy 619 %r2 = sdiv i8 %a, %r 620 ret i8 %r2 621} 622 623; Reassociate chains of extend(X) | (extend(Y) | Z). 624; Check that logical op is performed on a smaller type and then extended. 625 626define i64 @sext_or_chain(i64 %a, i16 %b, i16 %c) { 627; CHECK-LABEL: define {{[^@]+}}@sext_or_chain 628; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) { 629; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B]] to i64 630; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C]] to i64 631; CHECK-NEXT: [[OR:%.*]] = or i64 [[A]], [[CONV]] 632; CHECK-NEXT: [[OR2:%.*]] = or i64 [[OR]], [[CONV2]] 633; CHECK-NEXT: ret i64 [[OR2]] 634; 635 %conv = sext i16 %b to i64 636 %conv2 = sext i16 %c to i64 637 %or = or i64 %a, %conv 638 %or2 = or i64 %or, %conv2 639 ret i64 %or2 640} 641 642define i64 @zext_or_chain(i64 %a, i16 %b, i16 %c) { 643; CHECK-LABEL: define {{[^@]+}}@zext_or_chain 644; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) { 645; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[B]] to i64 646; CHECK-NEXT: [[CONV2:%.*]] = zext i16 [[C]] to i64 647; CHECK-NEXT: [[OR:%.*]] = or i64 [[A]], [[CONV]] 648; CHECK-NEXT: [[OR2:%.*]] = or i64 [[OR]], [[CONV2]] 649; CHECK-NEXT: ret i64 [[OR2]] 650; 651 %conv = zext i16 %b to i64 652 %conv2 = zext i16 %c to i64 653 %or = or i64 %a, %conv 654 %or2 = or i64 %or, %conv2 655 ret i64 %or2 656} 657 658define i64 @sext_and_chain(i64 %a, i16 %b, i16 %c) { 659; CHECK-LABEL: define {{[^@]+}}@sext_and_chain 660; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) { 661; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B]] to i64 662; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C]] to i64 663; CHECK-NEXT: [[AND:%.*]] = and i64 [[A]], [[CONV]] 664; CHECK-NEXT: [[AND2:%.*]] = and i64 [[AND]], [[CONV2]] 665; CHECK-NEXT: ret i64 [[AND2]] 666; 667 %conv = sext i16 %b to i64 668 %conv2 = sext i16 %c to i64 669 %and = and i64 %a, %conv 670 %and2 = and i64 %and, %conv2 671 ret i64 %and2 672} 673 674define i64 @zext_and_chain(i64 %a, i16 %b, i16 %c) { 675; CHECK-LABEL: define {{[^@]+}}@zext_and_chain 676; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) { 677; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[B]] to i64 678; CHECK-NEXT: [[CONV2:%.*]] = zext i16 [[C]] to i64 679; CHECK-NEXT: [[AND:%.*]] = and i64 [[A]], [[CONV]] 680; CHECK-NEXT: [[AND2:%.*]] = and i64 [[AND]], [[CONV2]] 681; CHECK-NEXT: ret i64 [[AND2]] 682; 683 %conv = zext i16 %b to i64 684 %conv2 = zext i16 %c to i64 685 %and = and i64 %a, %conv 686 %and2 = and i64 %and, %conv2 687 ret i64 %and2 688} 689 690define i64 @sext_xor_chain(i64 %a, i16 %b, i16 %c) { 691; CHECK-LABEL: define {{[^@]+}}@sext_xor_chain 692; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) { 693; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B]] to i64 694; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C]] to i64 695; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[A]], [[CONV]] 696; CHECK-NEXT: [[XOR2:%.*]] = xor i64 [[XOR]], [[CONV2]] 697; CHECK-NEXT: ret i64 [[XOR2]] 698; 699 %conv = sext i16 %b to i64 700 %conv2 = sext i16 %c to i64 701 %xor = xor i64 %a, %conv 702 %xor2 = xor i64 %xor, %conv2 703 ret i64 %xor2 704} 705 706define i64 @zext_xor_chain(i64 %a, i16 %b, i16 %c) { 707; CHECK-LABEL: define {{[^@]+}}@zext_xor_chain 708; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) { 709; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[B]] to i64 710; CHECK-NEXT: [[CONV2:%.*]] = zext i16 [[C]] to i64 711; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[A]], [[CONV]] 712; CHECK-NEXT: [[XOR2:%.*]] = xor i64 [[XOR]], [[CONV2]] 713; CHECK-NEXT: ret i64 [[XOR2]] 714; 715 %conv = zext i16 %b to i64 716 %conv2 = zext i16 %c to i64 717 %xor = xor i64 %a, %conv 718 %xor2 = xor i64 %xor, %conv2 719 ret i64 %xor2 720} 721 722; Negative test with more uses. 723define i64 @sext_or_chain_two_uses1(i64 %a, i16 %b, i16 %c, i64 %d) { 724; CHECK-LABEL: define {{[^@]+}}@sext_or_chain_two_uses1 725; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]], i64 [[D:%.*]]) { 726; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B]] to i64 727; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C]] to i64 728; CHECK-NEXT: [[OR:%.*]] = or i64 [[A]], [[CONV]] 729; CHECK-NEXT: [[OR2:%.*]] = or i64 [[OR]], [[CONV2]] 730; CHECK-NEXT: [[USE:%.*]] = udiv i64 [[OR]], [[D]] 731; CHECK-NEXT: [[RETVAL:%.*]] = udiv i64 [[OR2]], [[USE]] 732; CHECK-NEXT: ret i64 [[RETVAL]] 733; 734 %conv = sext i16 %b to i64 735 %conv2 = sext i16 %c to i64 736 ; %or has two uses 737 %or = or i64 %a, %conv 738 %or2 = or i64 %or, %conv2 739 %use = udiv i64 %or, %d 740 %retval = udiv i64 %or2, %use 741 ret i64 %retval 742} 743define i64 @sext_or_chain_two_uses2(i64 %a, i16 %b, i16 %c, i64 %d) { 744; CHECK-LABEL: define {{[^@]+}}@sext_or_chain_two_uses2 745; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]], i64 [[D:%.*]]) { 746; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B]] to i64 747; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C]] to i64 748; CHECK-NEXT: [[OR:%.*]] = or i64 [[A]], [[CONV]] 749; CHECK-NEXT: [[OR2:%.*]] = or i64 [[OR]], [[CONV2]] 750; CHECK-NEXT: [[USE1:%.*]] = udiv i64 [[OR2]], [[D]] 751; CHECK-NEXT: [[USE2:%.*]] = udiv i64 [[OR2]], [[USE1]] 752; CHECK-NEXT: ret i64 [[USE2]] 753; 754 %conv = sext i16 %b to i64 755 %conv2 = sext i16 %c to i64 756 %or = or i64 %a, %conv 757 ; %or2 has two uses 758 %or2 = or i64 %or, %conv2 759 %use1 = udiv i64 %or2, %d 760 %use2 = udiv i64 %or2, %use1 761 ret i64 %use2 762} 763 764; (a & ~b) & ~c --> a & ~(b | c) 765 766define i32 @not_and_and_not(i32 %a0, i32 %b, i32 %c) { 767; CHECK-LABEL: define {{[^@]+}}@not_and_and_not 768; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 769; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 770; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B]], [[C]] 771; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1 772; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[TMP2]] 773; CHECK-NEXT: ret i32 [[AND2]] 774; 775 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 776 %not1 = xor i32 %b, -1 777 %not2 = xor i32 %c, -1 778 %and1 = and i32 %a, %not1 779 %and2 = and i32 %and1, %not2 780 ret i32 %and2 781} 782 783define <4 x i64> @not_and_and_not_4i64(<4 x i64> %a0, <4 x i64> %b, <4 x i64> %c) { 784; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_4i64 785; CHECK-SAME: (<4 x i64> [[A0:%.*]], <4 x i64> [[B:%.*]], <4 x i64> [[C:%.*]]) { 786; CHECK-NEXT: [[A:%.*]] = sdiv <4 x i64> splat (i64 42), [[A0]] 787; CHECK-NEXT: [[TMP1:%.*]] = or <4 x i64> [[B]], [[C]] 788; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i64> [[TMP1]], splat (i64 -1) 789; CHECK-NEXT: [[AND2:%.*]] = and <4 x i64> [[A]], [[TMP2]] 790; CHECK-NEXT: ret <4 x i64> [[AND2]] 791; 792 %a = sdiv <4 x i64> <i64 42, i64 42, i64 42, i64 42>, %a0 ; thwart complexity-based canonicalization 793 %not1 = xor <4 x i64> %b, <i64 -1, i64 -1, i64 -1, i64 -1> 794 %not2 = xor <4 x i64> %c, <i64 -1, i64 -1, i64 -1, i64 -1> 795 %and1 = and <4 x i64> %a, %not1 796 %and2 = and <4 x i64> %and1, %not2 797 ret <4 x i64> %and2 798} 799 800; (~b & a) & ~c --> a & ~(b | c) 801 802define i32 @not_and_and_not_commute1(i32 %a, i32 %b, i32 %c) { 803; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_commute1 804; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 805; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B]], [[C]] 806; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1 807; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[TMP2]] 808; CHECK-NEXT: ret i32 [[AND2]] 809; 810 %not1 = xor i32 %b, -1 811 %not2 = xor i32 %c, -1 812 %and1 = and i32 %not1, %a 813 %and2 = and i32 %and1, %not2 814 ret i32 %and2 815} 816 817; ~c & (a & ~b) --> a & ~(b | c) 818 819define i32 @not_and_and_not_commute2_extra_not_use(i32 %a0, i32 %b, i32 %c) { 820; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_commute2_extra_not_use 821; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 822; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 823; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[C]], -1 824; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B]], [[C]] 825; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1 826; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[TMP2]] 827; CHECK-NEXT: call void @use(i32 [[NOT2]]) 828; CHECK-NEXT: ret i32 [[AND2]] 829; 830 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 831 %not1 = xor i32 %b, -1 832 %not2 = xor i32 %c, -1 833 %and1 = and i32 %a, %not1 834 %and2 = and i32 %not2, %and1 835 call void @use(i32 %not2) 836 ret i32 %and2 837} 838 839define i32 @not_and_and_not_extra_and1_use(i32 %a0, i32 %b, i32 %c) { 840; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_extra_and1_use 841; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 842; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 843; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[B]], -1 844; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[C]], -1 845; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[NOT1]] 846; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[NOT2]] 847; CHECK-NEXT: call void @use(i32 [[AND1]]) 848; CHECK-NEXT: ret i32 [[AND2]] 849; 850 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 851 %not1 = xor i32 %b, -1 852 %not2 = xor i32 %c, -1 853 %and1 = and i32 %a, %not1 854 %and2 = and i32 %and1, %not2 855 call void @use(i32 %and1) 856 ret i32 %and2 857} 858 859; (a | ~b) | ~c --> a | ~(b & c) 860 861define i32 @not_or_or_not(i32 %a0, i32 %b, i32 %c) { 862; CHECK-LABEL: define {{[^@]+}}@not_or_or_not 863; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 864; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 865; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B]], [[C]] 866; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1 867; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[TMP2]] 868; CHECK-NEXT: ret i32 [[OR2]] 869; 870 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 871 %not1 = xor i32 %b, -1 872 %not2 = xor i32 %c, -1 873 %or1 = or i32 %a, %not1 874 %or2 = or i32 %or1, %not2 875 ret i32 %or2 876} 877 878define <2 x i6> @not_or_or_not_2i6(<2 x i6> %a0, <2 x i6> %b, <2 x i6> %c) { 879; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_2i6 880; CHECK-SAME: (<2 x i6> [[A0:%.*]], <2 x i6> [[B:%.*]], <2 x i6> [[C:%.*]]) { 881; CHECK-NEXT: [[A:%.*]] = sdiv <2 x i6> splat (i6 3), [[A0]] 882; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i6> [[B]], [[C]] 883; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i6> [[TMP1]], splat (i6 -1) 884; CHECK-NEXT: [[OR2:%.*]] = or <2 x i6> [[A]], [[TMP2]] 885; CHECK-NEXT: ret <2 x i6> [[OR2]] 886; 887 %a = sdiv <2 x i6> <i6 3, i6 3>, %a0 ; thwart complexity-based canonicalization 888 %not1 = xor <2 x i6> %b, <i6 -1, i6 -1> 889 %not2 = xor <2 x i6> %c, <i6 -1, i6 poison> 890 %or1 = or <2 x i6> %a, %not1 891 %or2 = or <2 x i6> %or1, %not2 892 ret <2 x i6> %or2 893} 894 895; (~b | a) | ~c --> a | ~(b & c) 896 897define i32 @not_or_or_not_commute1(i32 %a, i32 %b, i32 %c) { 898; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_commute1 899; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 900; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B]], [[C]] 901; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1 902; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[TMP2]] 903; CHECK-NEXT: ret i32 [[OR2]] 904; 905 %not1 = xor i32 %b, -1 906 %not2 = xor i32 %c, -1 907 %or1 = or i32 %not1, %a 908 %or2 = or i32 %or1, %not2 909 ret i32 %or2 910} 911 912; ~c | (a | ~b) --> a | ~(b & c) 913 914define i32 @not_or_or_not_commute2_extra_not_use(i32 %a0, i32 %b, i32 %c) { 915; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_commute2_extra_not_use 916; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 917; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 918; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[C]], -1 919; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B]], [[C]] 920; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1 921; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[TMP2]] 922; CHECK-NEXT: call void @use(i32 [[NOT2]]) 923; CHECK-NEXT: ret i32 [[OR2]] 924; 925 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 926 %not1 = xor i32 %b, -1 927 %not2 = xor i32 %c, -1 928 %or1 = or i32 %a, %not1 929 %or2 = or i32 %not2, %or1 930 call void @use(i32 %not2) 931 ret i32 %or2 932} 933 934define i32 @not_or_or_not_extra_or1_use(i32 %a0, i32 %b, i32 %c) { 935; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_extra_or1_use 936; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 937; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 938; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[B]], -1 939; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[C]], -1 940; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]] 941; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[NOT2]] 942; CHECK-NEXT: call void @use(i32 [[OR1]]) 943; CHECK-NEXT: ret i32 [[OR2]] 944; 945 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 946 %not1 = xor i32 %b, -1 947 %not2 = xor i32 %c, -1 948 %or1 = or i32 %a, %not1 949 %or2 = or i32 %or1, %not2 950 call void @use(i32 %or1) 951 ret i32 %or2 952} 953 954; (c & ~(a | b)) | (b & ~(a | c)) --> ~a & (b ^ c) 955 956define i32 @or_not_and(i32 %a, i32 %b, i32 %c) { 957; CHECK-LABEL: define {{[^@]+}}@or_not_and 958; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 959; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 960; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1 961; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]] 962; CHECK-NEXT: ret i32 [[OR3]] 963; 964 %or1 = or i32 %a, %b 965 %not1 = xor i32 %or1, -1 966 %and1 = and i32 %not1, %c 967 %or2 = or i32 %a, %c 968 %not2 = xor i32 %or2, -1 969 %and2 = and i32 %not2, %b 970 %or3 = or i32 %and1, %and2 971 ret i32 %or3 972} 973 974define i32 @or_not_and_commute1(i32 %a, i32 %b0, i32 %c) { 975; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute1 976; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) { 977; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 978; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 979; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1 980; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]] 981; CHECK-NEXT: ret i32 [[OR3]] 982; 983 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 984 %or1 = or i32 %a, %b 985 %not1 = xor i32 %or1, -1 986 %and1 = and i32 %not1, %c 987 %or2 = or i32 %a, %c 988 %not2 = xor i32 %or2, -1 989 %and2 = and i32 %b, %not2 990 %or3 = or i32 %and1, %and2 991 ret i32 %or3 992} 993 994define i32 @or_not_and_commute2(i32 %a, i32 %b0, i32 %c) { 995; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute2 996; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) { 997; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 998; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 999; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1 1000; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]] 1001; CHECK-NEXT: ret i32 [[OR3]] 1002; 1003 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 1004 %or1 = or i32 %a, %b 1005 %not1 = xor i32 %or1, -1 1006 %and1 = and i32 %not1, %c 1007 %or2 = or i32 %a, %c 1008 %not2 = xor i32 %or2, -1 1009 %and2 = and i32 %b, %not2 1010 %or3 = or i32 %and2, %and1 1011 ret i32 %or3 1012} 1013 1014define i32 @or_not_and_commute3(i32 %a, i32 %b, i32 %c) { 1015; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute3 1016; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1017; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1018; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1 1019; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]] 1020; CHECK-NEXT: ret i32 [[OR3]] 1021; 1022 %or1 = or i32 %b, %a 1023 %not1 = xor i32 %or1, -1 1024 %and1 = and i32 %not1, %c 1025 %or2 = or i32 %c, %a 1026 %not2 = xor i32 %or2, -1 1027 %and2 = and i32 %not2, %b 1028 %or3 = or i32 %and1, %and2 1029 ret i32 %or3 1030} 1031 1032define i32 @or_not_and_commute4(i32 %a, i32 %b, i32 %c0) { 1033; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute4 1034; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) { 1035; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]] 1036; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1037; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1 1038; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]] 1039; CHECK-NEXT: ret i32 [[OR3]] 1040; 1041 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization 1042 %or1 = or i32 %a, %b 1043 %not1 = xor i32 %or1, -1 1044 %and1 = and i32 %c, %not1 1045 %or2 = or i32 %a, %c 1046 %not2 = xor i32 %or2, -1 1047 %and2 = and i32 %not2, %b 1048 %or3 = or i32 %and1, %and2 1049 ret i32 %or3 1050} 1051 1052define i32 @or_not_and_commute5(i32 %a0, i32 %b, i32 %c0) { 1053; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute5 1054; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) { 1055; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 1056; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]] 1057; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1058; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1 1059; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]] 1060; CHECK-NEXT: ret i32 [[OR3]] 1061; 1062 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 1063 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization 1064 %or1 = or i32 %a, %b 1065 %not1 = xor i32 %or1, -1 1066 %and1 = and i32 %c, %not1 1067 %or2 = or i32 %a, %c 1068 %not2 = xor i32 %or2, -1 1069 %and2 = and i32 %not2, %b 1070 %or3 = or i32 %and1, %and2 1071 ret i32 %or3 1072} 1073 1074define i32 @or_not_and_commute6(i32 %a, i32 %b, i32 %c) { 1075; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute6 1076; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1077; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1078; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1 1079; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]] 1080; CHECK-NEXT: ret i32 [[OR3]] 1081; 1082 %or1 = or i32 %a, %b 1083 %not1 = xor i32 %or1, -1 1084 %and1 = and i32 %not1, %c 1085 %or2 = or i32 %c, %a 1086 %not2 = xor i32 %or2, -1 1087 %and2 = and i32 %not2, %b 1088 %or3 = or i32 %and1, %and2 1089 ret i32 %or3 1090} 1091 1092define i32 @or_not_and_commute7(i32 %a, i32 %b, i32 %c) { 1093; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute7 1094; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1095; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1096; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1 1097; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]] 1098; CHECK-NEXT: ret i32 [[OR3]] 1099; 1100 %or1 = or i32 %b, %a 1101 %not1 = xor i32 %or1, -1 1102 %and1 = and i32 %not1, %c 1103 %or2 = or i32 %a, %c 1104 %not2 = xor i32 %or2, -1 1105 %and2 = and i32 %not2, %b 1106 %or3 = or i32 %and1, %and2 1107 ret i32 %or3 1108} 1109 1110define i32 @or_not_and_commute8(i32 %a0, i32 %b0, i32 %c) { 1111; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute8 1112; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) { 1113; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 1114; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 1115; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1116; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1 1117; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]] 1118; CHECK-NEXT: ret i32 [[OR3]] 1119; 1120 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 1121 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 1122 %or1 = or i32 %a, %b 1123 %not1 = xor i32 %or1, -1 1124 %and1 = and i32 %not1, %c 1125 %or2 = or i32 %c, %a 1126 %not2 = xor i32 %or2, -1 1127 %and2 = and i32 %b, %not2 1128 %or3 = or i32 %and1, %and2 1129 ret i32 %or3 1130} 1131 1132define i32 @or_not_and_commute9(i32 %a0, i32 %b0, i32 %c0) { 1133; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute9 1134; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C0:%.*]]) { 1135; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 1136; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 1137; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]] 1138; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1139; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1 1140; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]] 1141; CHECK-NEXT: ret i32 [[OR3]] 1142; 1143 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 1144 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 1145 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization 1146 %or1 = or i32 %a, %b 1147 %not1 = xor i32 %or1, -1 1148 %and1 = and i32 %not1, %c 1149 %or2 = or i32 %a, %c 1150 %not2 = xor i32 %or2, -1 1151 %and2 = and i32 %b, %not2 1152 %or3 = or i32 %and1, %and2 1153 ret i32 %or3 1154} 1155 1156define i32 @or_not_and_extra_not_use1(i32 %a, i32 %b, i32 %c) { 1157; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_not_use1 1158; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1159; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B]] 1160; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 1161; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1162; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1 1163; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]] 1164; CHECK-NEXT: call void @use(i32 [[NOT1]]) 1165; CHECK-NEXT: ret i32 [[OR3]] 1166; 1167 %or1 = or i32 %a, %b 1168 %not1 = xor i32 %or1, -1 1169 %and1 = and i32 %not1, %c 1170 %or2 = or i32 %a, %c 1171 %not2 = xor i32 %or2, -1 1172 %and2 = and i32 %not2, %b 1173 %or3 = or i32 %and1, %and2 1174 call void @use(i32 %not1) 1175 ret i32 %or3 1176} 1177 1178define i32 @or_not_and_extra_not_use2(i32 %a, i32 %b, i32 %c) { 1179; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_not_use2 1180; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1181; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B]] 1182; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 1183; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C]], [[NOT1]] 1184; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]] 1185; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1 1186; CHECK-NEXT: [[AND2:%.*]] = and i32 [[B]], [[NOT2]] 1187; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[AND2]] 1188; CHECK-NEXT: call void @use(i32 [[NOT2]]) 1189; CHECK-NEXT: ret i32 [[OR3]] 1190; 1191 %or1 = or i32 %a, %b 1192 %not1 = xor i32 %or1, -1 1193 %and1 = and i32 %not1, %c 1194 %or2 = or i32 %a, %c 1195 %not2 = xor i32 %or2, -1 1196 %and2 = and i32 %not2, %b 1197 %or3 = or i32 %and1, %and2 1198 call void @use(i32 %not2) 1199 ret i32 %or3 1200} 1201 1202define i32 @or_not_and_extra_and_use1(i32 %a, i32 %b, i32 %c) { 1203; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_and_use1 1204; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1205; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B]] 1206; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 1207; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C]], [[NOT1]] 1208; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1209; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1 1210; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]] 1211; CHECK-NEXT: call void @use(i32 [[AND1]]) 1212; CHECK-NEXT: ret i32 [[OR3]] 1213; 1214 %or1 = or i32 %a, %b 1215 %not1 = xor i32 %or1, -1 1216 %and1 = and i32 %not1, %c 1217 %or2 = or i32 %a, %c 1218 %not2 = xor i32 %or2, -1 1219 %and2 = and i32 %not2, %b 1220 %or3 = or i32 %and1, %and2 1221 call void @use(i32 %and1) 1222 ret i32 %or3 1223} 1224 1225define i32 @or_not_and_extra_and_use2(i32 %a, i32 %b, i32 %c) { 1226; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_and_use2 1227; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1228; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B]] 1229; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 1230; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C]], [[NOT1]] 1231; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]] 1232; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1 1233; CHECK-NEXT: [[AND2:%.*]] = and i32 [[B]], [[NOT2]] 1234; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[AND2]] 1235; CHECK-NEXT: call void @use(i32 [[AND2]]) 1236; CHECK-NEXT: ret i32 [[OR3]] 1237; 1238 %or1 = or i32 %a, %b 1239 %not1 = xor i32 %or1, -1 1240 %and1 = and i32 %not1, %c 1241 %or2 = or i32 %a, %c 1242 %not2 = xor i32 %or2, -1 1243 %and2 = and i32 %not2, %b 1244 %or3 = or i32 %and1, %and2 1245 call void @use(i32 %and2) 1246 ret i32 %or3 1247} 1248 1249define i32 @or_not_and_extra_or_use1(i32 %a, i32 %b, i32 %c) { 1250; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_or_use1 1251; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1252; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B]] 1253; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1254; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1 1255; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]] 1256; CHECK-NEXT: call void @use(i32 [[OR1]]) 1257; CHECK-NEXT: ret i32 [[OR3]] 1258; 1259 %or1 = or i32 %a, %b 1260 %not1 = xor i32 %or1, -1 1261 %and1 = and i32 %not1, %c 1262 %or2 = or i32 %a, %c 1263 %not2 = xor i32 %or2, -1 1264 %and2 = and i32 %not2, %b 1265 %or3 = or i32 %and1, %and2 1266 call void @use(i32 %or1) 1267 ret i32 %or3 1268} 1269 1270define i32 @or_not_and_extra_or_use2(i32 %a, i32 %b, i32 %c) { 1271; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_or_use2 1272; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1273; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]] 1274; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1275; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1 1276; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]] 1277; CHECK-NEXT: call void @use(i32 [[OR2]]) 1278; CHECK-NEXT: ret i32 [[OR3]] 1279; 1280 %or1 = or i32 %a, %b 1281 %not1 = xor i32 %or1, -1 1282 %and1 = and i32 %not1, %c 1283 %or2 = or i32 %a, %c 1284 %not2 = xor i32 %or2, -1 1285 %and2 = and i32 %not2, %b 1286 %or3 = or i32 %and1, %and2 1287 call void @use(i32 %or2) 1288 ret i32 %or3 1289} 1290 1291define i32 @or_not_and_wrong_c(i32 %a, i32 %b, i32 %c, i32 %d) { 1292; CHECK-LABEL: define {{[^@]+}}@or_not_and_wrong_c 1293; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) { 1294; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B]] 1295; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 1296; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C]], [[NOT1]] 1297; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[D]] 1298; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1 1299; CHECK-NEXT: [[AND2:%.*]] = and i32 [[B]], [[NOT2]] 1300; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[AND2]] 1301; CHECK-NEXT: ret i32 [[OR3]] 1302; 1303 %or1 = or i32 %a, %b 1304 %not1 = xor i32 %or1, -1 1305 %and1 = and i32 %not1, %c 1306 %or2 = or i32 %a, %d 1307 %not2 = xor i32 %or2, -1 1308 %and2 = and i32 %not2, %b 1309 %or3 = or i32 %and1, %and2 1310 ret i32 %or3 1311} 1312 1313define i32 @or_not_and_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) { 1314; CHECK-LABEL: define {{[^@]+}}@or_not_and_wrong_b 1315; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) { 1316; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B]] 1317; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 1318; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C]], [[NOT1]] 1319; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]] 1320; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1 1321; CHECK-NEXT: [[AND2:%.*]] = and i32 [[D]], [[NOT2]] 1322; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[AND2]] 1323; CHECK-NEXT: ret i32 [[OR3]] 1324; 1325 %or1 = or i32 %a, %b 1326 %not1 = xor i32 %or1, -1 1327 %and1 = and i32 %not1, %c 1328 %or2 = or i32 %a, %c 1329 %not2 = xor i32 %or2, -1 1330 %and2 = and i32 %not2, %d 1331 %or3 = or i32 %and1, %and2 1332 ret i32 %or3 1333} 1334 1335; (c | ~(a & b)) & (b | ~(a & c)) --> ~(a & (b ^ c)) 1336 1337define i32 @and_not_or(i32 %a, i32 %b, i32 %c) { 1338; CHECK-LABEL: define {{[^@]+}}@and_not_or 1339; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1340; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1341; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 1342; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 1343; CHECK-NEXT: ret i32 [[AND3]] 1344; 1345 %and1 = and i32 %a, %b 1346 %not1 = xor i32 %and1, -1 1347 %or1 = or i32 %not1, %c 1348 %and2 = and i32 %a, %c 1349 %not2 = xor i32 %and2, -1 1350 %or2 = or i32 %not2, %b 1351 %and3 = and i32 %or1, %or2 1352 ret i32 %and3 1353} 1354 1355define i32 @and_not_or_commute1(i32 %a, i32 %b0, i32 %c) { 1356; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute1 1357; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) { 1358; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 1359; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1360; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 1361; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 1362; CHECK-NEXT: ret i32 [[AND3]] 1363; 1364 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 1365 %and1 = and i32 %a, %b 1366 %not1 = xor i32 %and1, -1 1367 %or1 = or i32 %not1, %c 1368 %and2 = and i32 %a, %c 1369 %not2 = xor i32 %and2, -1 1370 %or2 = or i32 %b, %not2 1371 %and3 = and i32 %or1, %or2 1372 ret i32 %and3 1373} 1374 1375define i32 @and_not_or_commute2(i32 %a, i32 %b0, i32 %c) { 1376; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute2 1377; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) { 1378; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 1379; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 1380; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 1381; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 1382; CHECK-NEXT: ret i32 [[AND3]] 1383; 1384 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 1385 %and1 = and i32 %a, %b 1386 %not1 = xor i32 %and1, -1 1387 %or1 = or i32 %not1, %c 1388 %and2 = and i32 %a, %c 1389 %not2 = xor i32 %and2, -1 1390 %or2 = or i32 %b, %not2 1391 %and3 = and i32 %or2, %or1 1392 ret i32 %and3 1393} 1394 1395define i32 @and_not_or_commute3(i32 %a, i32 %b, i32 %c) { 1396; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute3 1397; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1398; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1399; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 1400; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 1401; CHECK-NEXT: ret i32 [[AND3]] 1402; 1403 %and1 = and i32 %b, %a 1404 %not1 = xor i32 %and1, -1 1405 %or1 = or i32 %not1, %c 1406 %and2 = and i32 %c, %a 1407 %not2 = xor i32 %and2, -1 1408 %or2 = or i32 %not2, %b 1409 %and3 = and i32 %or1, %or2 1410 ret i32 %and3 1411} 1412 1413define i32 @and_not_or_commute4(i32 %a, i32 %b, i32 %c0) { 1414; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute4 1415; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) { 1416; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]] 1417; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1418; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 1419; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 1420; CHECK-NEXT: ret i32 [[AND3]] 1421; 1422 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization 1423 %and1 = and i32 %a, %b 1424 %not1 = xor i32 %and1, -1 1425 %or1 = or i32 %c, %not1 1426 %and2 = and i32 %a, %c 1427 %not2 = xor i32 %and2, -1 1428 %or2 = or i32 %not2, %b 1429 %and3 = and i32 %or1, %or2 1430 ret i32 %and3 1431} 1432 1433define i32 @and_not_or_commute5(i32 %a0, i32 %b, i32 %c0) { 1434; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute5 1435; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) { 1436; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 1437; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]] 1438; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1439; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 1440; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 1441; CHECK-NEXT: ret i32 [[AND3]] 1442; 1443 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 1444 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization 1445 %and1 = and i32 %a, %b 1446 %not1 = xor i32 %and1, -1 1447 %or1 = or i32 %c, %not1 1448 %and2 = and i32 %a, %c 1449 %not2 = xor i32 %and2, -1 1450 %or2 = or i32 %not2, %b 1451 %and3 = and i32 %or1, %or2 1452 ret i32 %and3 1453} 1454 1455define i32 @and_not_or_commute6(i32 %a, i32 %b, i32 %c) { 1456; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute6 1457; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1458; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1459; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 1460; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 1461; CHECK-NEXT: ret i32 [[AND3]] 1462; 1463 %and1 = and i32 %a, %b 1464 %not1 = xor i32 %and1, -1 1465 %or1 = or i32 %not1, %c 1466 %and2 = and i32 %c, %a 1467 %not2 = xor i32 %and2, -1 1468 %or2 = or i32 %not2, %b 1469 %and3 = and i32 %or1, %or2 1470 ret i32 %and3 1471} 1472 1473define i32 @and_not_or_commute7(i32 %a, i32 %b, i32 %c) { 1474; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute7 1475; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1476; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1477; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 1478; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 1479; CHECK-NEXT: ret i32 [[AND3]] 1480; 1481 %and1 = and i32 %b, %a 1482 %not1 = xor i32 %and1, -1 1483 %or1 = or i32 %not1, %c 1484 %and2 = and i32 %a, %c 1485 %not2 = xor i32 %and2, -1 1486 %or2 = or i32 %not2, %b 1487 %and3 = and i32 %or1, %or2 1488 ret i32 %and3 1489} 1490 1491define i32 @and_not_or_commute8(i32 %a0, i32 %b0, i32 %c) { 1492; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute8 1493; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) { 1494; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 1495; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 1496; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1497; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 1498; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 1499; CHECK-NEXT: ret i32 [[AND3]] 1500; 1501 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 1502 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 1503 %and1 = and i32 %a, %b 1504 %not1 = xor i32 %and1, -1 1505 %or1 = or i32 %not1, %c 1506 %and2 = and i32 %c, %a 1507 %not2 = xor i32 %and2, -1 1508 %or2 = or i32 %b, %not2 1509 %and3 = and i32 %or1, %or2 1510 ret i32 %and3 1511} 1512 1513define i32 @and_not_or_commute9(i32 %a0, i32 %b0, i32 %c0) { 1514; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute9 1515; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C0:%.*]]) { 1516; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 1517; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 1518; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]] 1519; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1520; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 1521; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 1522; CHECK-NEXT: ret i32 [[AND3]] 1523; 1524 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 1525 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 1526 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization 1527 %and1 = and i32 %a, %b 1528 %not1 = xor i32 %and1, -1 1529 %or1 = or i32 %not1, %c 1530 %and2 = and i32 %a, %c 1531 %not2 = xor i32 %and2, -1 1532 %or2 = or i32 %b, %not2 1533 %and3 = and i32 %or1, %or2 1534 ret i32 %and3 1535} 1536 1537define i32 @and_not_or_extra_not_use1(i32 %a, i32 %b, i32 %c) { 1538; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_not_use1 1539; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1540; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B]] 1541; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 1542; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1543; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 1544; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 1545; CHECK-NEXT: call void @use(i32 [[NOT1]]) 1546; CHECK-NEXT: ret i32 [[AND3]] 1547; 1548 %and1 = and i32 %a, %b 1549 %not1 = xor i32 %and1, -1 1550 %or1 = or i32 %not1, %c 1551 %and2 = and i32 %a, %c 1552 %not2 = xor i32 %and2, -1 1553 %or2 = or i32 %not2, %b 1554 %and3 = and i32 %or1, %or2 1555 call void @use(i32 %not1) 1556 ret i32 %and3 1557} 1558 1559define i32 @and_not_or_extra_not_use2(i32 %a, i32 %b, i32 %c) { 1560; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_not_use2 1561; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1562; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B]] 1563; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 1564; CHECK-NEXT: [[OR1:%.*]] = or i32 [[C]], [[NOT1]] 1565; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]] 1566; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1 1567; CHECK-NEXT: [[OR2:%.*]] = or i32 [[B]], [[NOT2]] 1568; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR1]], [[OR2]] 1569; CHECK-NEXT: call void @use(i32 [[NOT2]]) 1570; CHECK-NEXT: ret i32 [[AND3]] 1571; 1572 %and1 = and i32 %a, %b 1573 %not1 = xor i32 %and1, -1 1574 %or1 = or i32 %not1, %c 1575 %and2 = and i32 %a, %c 1576 %not2 = xor i32 %and2, -1 1577 %or2 = or i32 %not2, %b 1578 %and3 = and i32 %or1, %or2 1579 call void @use(i32 %not2) 1580 ret i32 %and3 1581} 1582 1583define i32 @and_not_or_extra_and_use1(i32 %a, i32 %b, i32 %c) { 1584; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_and_use1 1585; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1586; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B]] 1587; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 1588; CHECK-NEXT: [[OR1:%.*]] = or i32 [[C]], [[NOT1]] 1589; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1590; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 1591; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 1592; CHECK-NEXT: call void @use(i32 [[OR1]]) 1593; CHECK-NEXT: ret i32 [[AND3]] 1594; 1595 %and1 = and i32 %a, %b 1596 %not1 = xor i32 %and1, -1 1597 %or1 = or i32 %not1, %c 1598 %and2 = and i32 %a, %c 1599 %not2 = xor i32 %and2, -1 1600 %or2 = or i32 %not2, %b 1601 %and3 = and i32 %or1, %or2 1602 call void @use(i32 %or1) 1603 ret i32 %and3 1604} 1605 1606define i32 @and_not_or_extra_and_use2(i32 %a, i32 %b, i32 %c) { 1607; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_and_use2 1608; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1609; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B]] 1610; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 1611; CHECK-NEXT: [[OR1:%.*]] = or i32 [[C]], [[NOT1]] 1612; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]] 1613; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1 1614; CHECK-NEXT: [[OR2:%.*]] = or i32 [[B]], [[NOT2]] 1615; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR1]], [[OR2]] 1616; CHECK-NEXT: call void @use(i32 [[OR2]]) 1617; CHECK-NEXT: ret i32 [[AND3]] 1618; 1619 %and1 = and i32 %a, %b 1620 %not1 = xor i32 %and1, -1 1621 %or1 = or i32 %not1, %c 1622 %and2 = and i32 %a, %c 1623 %not2 = xor i32 %and2, -1 1624 %or2 = or i32 %not2, %b 1625 %and3 = and i32 %or1, %or2 1626 call void @use(i32 %or2) 1627 ret i32 %and3 1628} 1629 1630define i32 @and_not_or_extra_or_use1(i32 %a, i32 %b, i32 %c) { 1631; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_or_use1 1632; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1633; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B]] 1634; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1635; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 1636; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 1637; CHECK-NEXT: call void @use(i32 [[AND1]]) 1638; CHECK-NEXT: ret i32 [[AND3]] 1639; 1640 %and1 = and i32 %a, %b 1641 %not1 = xor i32 %and1, -1 1642 %or1 = or i32 %not1, %c 1643 %and2 = and i32 %a, %c 1644 %not2 = xor i32 %and2, -1 1645 %or2 = or i32 %not2, %b 1646 %and3 = and i32 %or1, %or2 1647 call void @use(i32 %and1) 1648 ret i32 %and3 1649} 1650 1651define i32 @and_not_or_extra_or_use2(i32 %a, i32 %b, i32 %c) { 1652; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_or_use2 1653; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1654; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]] 1655; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 1656; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 1657; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 1658; CHECK-NEXT: call void @use(i32 [[AND2]]) 1659; CHECK-NEXT: ret i32 [[AND3]] 1660; 1661 %and1 = and i32 %a, %b 1662 %not1 = xor i32 %and1, -1 1663 %or1 = or i32 %not1, %c 1664 %and2 = and i32 %a, %c 1665 %not2 = xor i32 %and2, -1 1666 %or2 = or i32 %not2, %b 1667 %and3 = and i32 %or1, %or2 1668 call void @use(i32 %and2) 1669 ret i32 %and3 1670} 1671 1672define i32 @and_not_or_wrong_c(i32 %a, i32 %b, i32 %c, i32 %d) { 1673; CHECK-LABEL: define {{[^@]+}}@and_not_or_wrong_c 1674; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) { 1675; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B]] 1676; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 1677; CHECK-NEXT: [[OR1:%.*]] = or i32 [[C]], [[NOT1]] 1678; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[D]] 1679; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1 1680; CHECK-NEXT: [[OR2:%.*]] = or i32 [[B]], [[NOT2]] 1681; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR1]], [[OR2]] 1682; CHECK-NEXT: ret i32 [[AND3]] 1683; 1684 %and1 = and i32 %a, %b 1685 %not1 = xor i32 %and1, -1 1686 %or1 = or i32 %not1, %c 1687 %and2 = and i32 %a, %d 1688 %not2 = xor i32 %and2, -1 1689 %or2 = or i32 %not2, %b 1690 %and3 = and i32 %or1, %or2 1691 ret i32 %and3 1692} 1693 1694define i32 @and_not_or_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) { 1695; CHECK-LABEL: define {{[^@]+}}@and_not_or_wrong_b 1696; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) { 1697; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B]] 1698; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 1699; CHECK-NEXT: [[OR1:%.*]] = or i32 [[C]], [[NOT1]] 1700; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]] 1701; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1 1702; CHECK-NEXT: [[OR2:%.*]] = or i32 [[D]], [[NOT2]] 1703; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR1]], [[OR2]] 1704; CHECK-NEXT: ret i32 [[AND3]] 1705; 1706 %and1 = and i32 %a, %b 1707 %not1 = xor i32 %and1, -1 1708 %or1 = or i32 %not1, %c 1709 %and2 = and i32 %a, %c 1710 %not2 = xor i32 %and2, -1 1711 %or2 = or i32 %not2, %d 1712 %and3 = and i32 %or1, %or2 1713 ret i32 %and3 1714} 1715 1716; (b & ~(a | c)) | ~(a | b) --> ~((b & c) | a) 1717 1718define i32 @or_and_not_not(i32 %a, i32 %b, i32 %c) { 1719; CHECK-LABEL: define {{[^@]+}}@or_and_not_not 1720; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1721; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]] 1722; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 1723; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 1724; CHECK-NEXT: ret i32 [[OR3]] 1725; 1726 %or1 = or i32 %b, %a 1727 %not1 = xor i32 %or1, -1 1728 %or2 = or i32 %a, %c 1729 %not2 = xor i32 %or2, -1 1730 %and = and i32 %not2, %b 1731 %or3 = or i32 %and, %not1 1732 ret i32 %or3 1733} 1734 1735define i32 @or_and_not_not_commute1(i32 %a, i32 %b0, i32 %c) { 1736; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute1 1737; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) { 1738; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 1739; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]] 1740; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 1741; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 1742; CHECK-NEXT: ret i32 [[OR3]] 1743; 1744 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 1745 %or1 = or i32 %b, %a 1746 %not1 = xor i32 %or1, -1 1747 %or2 = or i32 %a, %c 1748 %not2 = xor i32 %or2, -1 1749 %and = and i32 %b, %not2 1750 %or3 = or i32 %and, %not1 1751 ret i32 %or3 1752} 1753 1754define i32 @or_and_not_not_commute2(i32 %a, i32 %b, i32 %c) { 1755; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute2 1756; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1757; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]] 1758; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 1759; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 1760; CHECK-NEXT: ret i32 [[OR3]] 1761; 1762 %or1 = or i32 %b, %a 1763 %not1 = xor i32 %or1, -1 1764 %or2 = or i32 %a, %c 1765 %not2 = xor i32 %or2, -1 1766 %and = and i32 %not2, %b 1767 %or3 = or i32 %and, %not1 1768 ret i32 %or3 1769} 1770 1771define i32 @or_and_not_not_commute3(i32 %a, i32 %b, i32 %c) { 1772; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute3 1773; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1774; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]] 1775; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 1776; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 1777; CHECK-NEXT: ret i32 [[OR3]] 1778; 1779 %or1 = or i32 %b, %a 1780 %not1 = xor i32 %or1, -1 1781 %or2 = or i32 %c, %a 1782 %not2 = xor i32 %or2, -1 1783 %and = and i32 %not2, %b 1784 %or3 = or i32 %and, %not1 1785 ret i32 %or3 1786} 1787 1788define i32 @or_and_not_not_commute4(i32 %a, i32 %b, i32 %c) { 1789; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute4 1790; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1791; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]] 1792; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 1793; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 1794; CHECK-NEXT: ret i32 [[OR3]] 1795; 1796 %or1 = or i32 %a, %b 1797 %not1 = xor i32 %or1, -1 1798 %or2 = or i32 %a, %c 1799 %not2 = xor i32 %or2, -1 1800 %and = and i32 %not2, %b 1801 %or3 = or i32 %and, %not1 1802 ret i32 %or3 1803} 1804 1805define i32 @or_and_not_not_commute5(i32 %a, i32 %b, i32 %c) { 1806; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute5 1807; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1808; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]] 1809; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 1810; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 1811; CHECK-NEXT: ret i32 [[OR3]] 1812; 1813 %or1 = or i32 %b, %a 1814 %not1 = xor i32 %or1, -1 1815 %or2 = or i32 %a, %c 1816 %not2 = xor i32 %or2, -1 1817 %and = and i32 %not2, %b 1818 %or3 = or i32 %not1, %and 1819 ret i32 %or3 1820} 1821 1822define i32 @or_and_not_not_commute6(i32 %a, i32 %b0, i32 %c) { 1823; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute6 1824; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) { 1825; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 1826; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]] 1827; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 1828; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 1829; CHECK-NEXT: ret i32 [[OR3]] 1830; 1831 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 1832 %or1 = or i32 %b, %a 1833 %not1 = xor i32 %or1, -1 1834 %or2 = or i32 %c, %a 1835 %not2 = xor i32 %or2, -1 1836 %and = and i32 %b, %not2 1837 %or3 = or i32 %and, %not1 1838 ret i32 %or3 1839} 1840 1841define i32 @or_and_not_not_commute7(i32 %a, i32 %b, i32 %c) { 1842; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute7 1843; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1844; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]] 1845; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 1846; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 1847; CHECK-NEXT: ret i32 [[OR3]] 1848; 1849 %or1 = or i32 %a, %b 1850 %not1 = xor i32 %or1, -1 1851 %or2 = or i32 %c, %a 1852 %not2 = xor i32 %or2, -1 1853 %and = and i32 %not2, %b 1854 %or3 = or i32 %and, %not1 1855 ret i32 %or3 1856} 1857 1858define i32 @or_and_not_not_extra_not_use1(i32 %a, i32 %b, i32 %c) { 1859; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_not_use1 1860; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1861; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]] 1862; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 1863; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]] 1864; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1 1865; CHECK-NEXT: [[AND:%.*]] = and i32 [[B]], [[NOT2]] 1866; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]] 1867; CHECK-NEXT: call void @use(i32 [[NOT1]]) 1868; CHECK-NEXT: ret i32 [[OR3]] 1869; 1870 %or1 = or i32 %b, %a 1871 %not1 = xor i32 %or1, -1 1872 %or2 = or i32 %a, %c 1873 %not2 = xor i32 %or2, -1 1874 %and = and i32 %not2, %b 1875 %or3 = or i32 %and, %not1 1876 call void @use(i32 %not1) 1877 ret i32 %or3 1878} 1879 1880define i32 @or_and_not_not_extra_not_use2(i32 %a, i32 %b, i32 %c) { 1881; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_not_use2 1882; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1883; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]] 1884; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1 1885; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]] 1886; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 1887; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 1888; CHECK-NEXT: call void @use(i32 [[NOT2]]) 1889; CHECK-NEXT: ret i32 [[OR3]] 1890; 1891 %or1 = or i32 %b, %a 1892 %not1 = xor i32 %or1, -1 1893 %or2 = or i32 %a, %c 1894 %not2 = xor i32 %or2, -1 1895 %and = and i32 %not2, %b 1896 %or3 = or i32 %and, %not1 1897 call void @use(i32 %not2) 1898 ret i32 %or3 1899} 1900 1901define i32 @or_and_not_not_extra_and_use(i32 %a, i32 %b, i32 %c) { 1902; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_and_use 1903; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1904; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]] 1905; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1 1906; CHECK-NEXT: [[AND:%.*]] = and i32 [[B]], [[NOT2]] 1907; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]] 1908; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 1909; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 1910; CHECK-NEXT: call void @use(i32 [[AND]]) 1911; CHECK-NEXT: ret i32 [[OR3]] 1912; 1913 %or1 = or i32 %b, %a 1914 %not1 = xor i32 %or1, -1 1915 %or2 = or i32 %a, %c 1916 %not2 = xor i32 %or2, -1 1917 %and = and i32 %not2, %b 1918 %or3 = or i32 %and, %not1 1919 call void @use(i32 %and) 1920 ret i32 %or3 1921} 1922 1923define i32 @or_and_not_not_extra_or_use1(i32 %a, i32 %b, i32 %c) { 1924; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_or_use1 1925; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1926; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]] 1927; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 1928; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]] 1929; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1 1930; CHECK-NEXT: [[AND:%.*]] = and i32 [[B]], [[NOT2]] 1931; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]] 1932; CHECK-NEXT: call void @use(i32 [[OR1]]) 1933; CHECK-NEXT: ret i32 [[OR3]] 1934; 1935 %or1 = or i32 %b, %a 1936 %not1 = xor i32 %or1, -1 1937 %or2 = or i32 %a, %c 1938 %not2 = xor i32 %or2, -1 1939 %and = and i32 %not2, %b 1940 %or3 = or i32 %and, %not1 1941 call void @use(i32 %or1) 1942 ret i32 %or3 1943} 1944 1945define i32 @or_and_not_not_extra_or_use2(i32 %a, i32 %b, i32 %c) { 1946; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_or_use2 1947; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1948; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]] 1949; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]] 1950; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 1951; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 1952; CHECK-NEXT: call void @use(i32 [[OR2]]) 1953; CHECK-NEXT: ret i32 [[OR3]] 1954; 1955 %or1 = or i32 %b, %a 1956 %not1 = xor i32 %or1, -1 1957 %or2 = or i32 %a, %c 1958 %not2 = xor i32 %or2, -1 1959 %and = and i32 %not2, %b 1960 %or3 = or i32 %and, %not1 1961 call void @use(i32 %or2) 1962 ret i32 %or3 1963} 1964 1965; Check the use limit. It can be adjusted in the future in terms of 1966; LHS and RHS uses distribution to be more flexible. 1967define i32 @or_and_not_not_2_extra_uses(i32 %a, i32 %b, i32 %c) { 1968; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_2_extra_uses 1969; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 1970; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]] 1971; CHECK-NEXT: call void @use(i32 [[OR1]]) 1972; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 1973; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]] 1974; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1 1975; CHECK-NEXT: [[AND:%.*]] = and i32 [[B]], [[NOT2]] 1976; CHECK-NEXT: call void @use(i32 [[AND]]) 1977; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]] 1978; CHECK-NEXT: ret i32 [[OR3]] 1979; 1980 %or1 = or i32 %b, %a 1981 call void @use(i32 %or1) 1982 %not1 = xor i32 %or1, -1 1983 %or2 = or i32 %a, %c 1984 %not2 = xor i32 %or2, -1 1985 %and = and i32 %not2, %b 1986 call void @use(i32 %and) 1987 %or3 = or i32 %not1, %and 1988 ret i32 %or3 1989} 1990 1991define i32 @or_and_not_not_wrong_a(i32 %a, i32 %b, i32 %c, i32 %d) { 1992; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_wrong_a 1993; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) { 1994; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[D]] 1995; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 1996; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]] 1997; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1 1998; CHECK-NEXT: [[AND:%.*]] = and i32 [[B]], [[NOT2]] 1999; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]] 2000; CHECK-NEXT: ret i32 [[OR3]] 2001; 2002 %or1 = or i32 %b, %d 2003 %not1 = xor i32 %or1, -1 2004 %or2 = or i32 %a, %c 2005 %not2 = xor i32 %or2, -1 2006 %and = and i32 %not2, %b 2007 %or3 = or i32 %and, %not1 2008 ret i32 %or3 2009} 2010 2011define i32 @or_and_not_not_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) { 2012; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_wrong_b 2013; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) { 2014; CHECK-NEXT: [[OR1:%.*]] = or i32 [[D]], [[A]] 2015; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 2016; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]] 2017; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1 2018; CHECK-NEXT: [[AND:%.*]] = and i32 [[B]], [[NOT2]] 2019; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]] 2020; CHECK-NEXT: ret i32 [[OR3]] 2021; 2022 %or1 = or i32 %d, %a 2023 %not1 = xor i32 %or1, -1 2024 %or2 = or i32 %a, %c 2025 %not2 = xor i32 %or2, -1 2026 %and = and i32 %not2, %b 2027 %or3 = or i32 %and, %not1 2028 ret i32 %or3 2029} 2030 2031; (b | ~(a & c)) & ~(a & b) --> ~((b | c) & a) 2032 2033define i32 @and_or_not_not(i32 %a, i32 %b, i32 %c) { 2034; CHECK-LABEL: define {{[^@]+}}@and_or_not_not 2035; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2036; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]] 2037; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 2038; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 2039; CHECK-NEXT: ret i32 [[AND3]] 2040; 2041 %and1 = and i32 %b, %a 2042 %not1 = xor i32 %and1, -1 2043 %and2 = and i32 %a, %c 2044 %not2 = xor i32 %and2, -1 2045 %or = or i32 %not2, %b 2046 %and3 = and i32 %or, %not1 2047 ret i32 %and3 2048} 2049 2050define i32 @and_or_not_not_commute1(i32 %a, i32 %b0, i32 %c) { 2051; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute1 2052; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) { 2053; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 2054; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]] 2055; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 2056; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 2057; CHECK-NEXT: ret i32 [[AND3]] 2058; 2059 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 2060 %and1 = and i32 %b, %a 2061 %not1 = xor i32 %and1, -1 2062 %and2 = and i32 %a, %c 2063 %not2 = xor i32 %and2, -1 2064 %or = or i32 %b, %not2 2065 %and3 = and i32 %or, %not1 2066 ret i32 %and3 2067} 2068 2069define i32 @and_or_not_not_commute2(i32 %a, i32 %b, i32 %c) { 2070; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute2 2071; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2072; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]] 2073; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 2074; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 2075; CHECK-NEXT: ret i32 [[AND3]] 2076; 2077 %and1 = and i32 %b, %a 2078 %not1 = xor i32 %and1, -1 2079 %and2 = and i32 %a, %c 2080 %not2 = xor i32 %and2, -1 2081 %or = or i32 %not2, %b 2082 %and3 = and i32 %or, %not1 2083 ret i32 %and3 2084} 2085 2086define i32 @and_or_not_not_commute3(i32 %a, i32 %b, i32 %c) { 2087; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute3 2088; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2089; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]] 2090; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 2091; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 2092; CHECK-NEXT: ret i32 [[AND3]] 2093; 2094 %and1 = and i32 %b, %a 2095 %not1 = xor i32 %and1, -1 2096 %and2 = and i32 %c, %a 2097 %not2 = xor i32 %and2, -1 2098 %or = or i32 %not2, %b 2099 %and3 = and i32 %or, %not1 2100 ret i32 %and3 2101} 2102 2103define i32 @and_or_not_not_commute4(i32 %a, i32 %b, i32 %c) { 2104; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute4 2105; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2106; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]] 2107; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 2108; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 2109; CHECK-NEXT: ret i32 [[AND3]] 2110; 2111 %and1 = and i32 %a, %b 2112 %not1 = xor i32 %and1, -1 2113 %and2 = and i32 %a, %c 2114 %not2 = xor i32 %and2, -1 2115 %or = or i32 %not2, %b 2116 %and3 = and i32 %or, %not1 2117 ret i32 %and3 2118} 2119 2120define i32 @and_or_not_not_commute5(i32 %a, i32 %b, i32 %c) { 2121; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute5 2122; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2123; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]] 2124; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 2125; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 2126; CHECK-NEXT: ret i32 [[AND3]] 2127; 2128 %and1 = and i32 %b, %a 2129 %not1 = xor i32 %and1, -1 2130 %and2 = and i32 %a, %c 2131 %not2 = xor i32 %and2, -1 2132 %or = or i32 %not2, %b 2133 %and3 = and i32 %not1, %or 2134 ret i32 %and3 2135} 2136 2137define i32 @and_or_not_not_commute6(i32 %a, i32 %b0, i32 %c) { 2138; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute6 2139; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) { 2140; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 2141; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]] 2142; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 2143; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 2144; CHECK-NEXT: ret i32 [[AND3]] 2145; 2146 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 2147 %and1 = and i32 %b, %a 2148 %not1 = xor i32 %and1, -1 2149 %and2 = and i32 %c, %a 2150 %not2 = xor i32 %and2, -1 2151 %or = or i32 %b, %not2 2152 %and3 = and i32 %or, %not1 2153 ret i32 %and3 2154} 2155 2156define i32 @and_or_not_not_commute7(i32 %a, i32 %b, i32 %c) { 2157; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute7 2158; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2159; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]] 2160; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 2161; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 2162; CHECK-NEXT: ret i32 [[AND3]] 2163; 2164 %and1 = and i32 %a, %b 2165 %not1 = xor i32 %and1, -1 2166 %and2 = and i32 %c, %a 2167 %not2 = xor i32 %and2, -1 2168 %or = or i32 %not2, %b 2169 %and3 = and i32 %or, %not1 2170 ret i32 %and3 2171} 2172 2173define i32 @and_or_not_not_extra_not_use1(i32 %a, i32 %b, i32 %c) { 2174; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_not_use1 2175; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2176; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]] 2177; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 2178; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]] 2179; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1 2180; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOT2]] 2181; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND1]], [[OR]] 2182; CHECK-NEXT: call void @use(i32 [[NOT1]]) 2183; CHECK-NEXT: ret i32 [[AND3]] 2184; 2185 %and1 = and i32 %b, %a 2186 %not1 = xor i32 %and1, -1 2187 %and2 = and i32 %a, %c 2188 %not2 = xor i32 %and2, -1 2189 %or = or i32 %not2, %b 2190 %and3 = and i32 %or, %not1 2191 call void @use(i32 %not1) 2192 ret i32 %and3 2193} 2194 2195define i32 @and_or_not_not_extra_not_use2(i32 %a, i32 %b, i32 %c) { 2196; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_not_use2 2197; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2198; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]] 2199; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1 2200; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]] 2201; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 2202; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 2203; CHECK-NEXT: call void @use(i32 [[NOT2]]) 2204; CHECK-NEXT: ret i32 [[AND3]] 2205; 2206 %and1 = and i32 %b, %a 2207 %not1 = xor i32 %and1, -1 2208 %and2 = and i32 %a, %c 2209 %not2 = xor i32 %and2, -1 2210 %or = or i32 %not2, %b 2211 %and3 = and i32 %or, %not1 2212 call void @use(i32 %not2) 2213 ret i32 %and3 2214} 2215 2216define i32 @and_or_not_not_extra_and_use(i32 %a, i32 %b, i32 %c) { 2217; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_and_use 2218; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2219; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]] 2220; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1 2221; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOT2]] 2222; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]] 2223; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 2224; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 2225; CHECK-NEXT: call void @use(i32 [[OR]]) 2226; CHECK-NEXT: ret i32 [[AND3]] 2227; 2228 %and1 = and i32 %b, %a 2229 %not1 = xor i32 %and1, -1 2230 %and2 = and i32 %a, %c 2231 %not2 = xor i32 %and2, -1 2232 %or = or i32 %not2, %b 2233 %and3 = and i32 %or, %not1 2234 call void @use(i32 %or) 2235 ret i32 %and3 2236} 2237 2238define i32 @and_or_not_not_extra_or_use1(i32 %a, i32 %b, i32 %c) { 2239; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_or_use1 2240; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2241; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]] 2242; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]] 2243; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1 2244; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOT2]] 2245; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND1]], [[OR]] 2246; CHECK-NEXT: call void @use(i32 [[AND1]]) 2247; CHECK-NEXT: ret i32 [[AND3]] 2248; 2249 %and1 = and i32 %b, %a 2250 %not1 = xor i32 %and1, -1 2251 %and2 = and i32 %a, %c 2252 %not2 = xor i32 %and2, -1 2253 %or = or i32 %not2, %b 2254 %and3 = and i32 %or, %not1 2255 call void @use(i32 %and1) 2256 ret i32 %and3 2257} 2258 2259define i32 @and_or_not_not_extra_or_use2(i32 %a, i32 %b, i32 %c) { 2260; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_or_use2 2261; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2262; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]] 2263; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]] 2264; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]] 2265; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1 2266; CHECK-NEXT: call void @use(i32 [[AND2]]) 2267; CHECK-NEXT: ret i32 [[AND3]] 2268; 2269 %and1 = and i32 %b, %a 2270 %not1 = xor i32 %and1, -1 2271 %and2 = and i32 %a, %c 2272 %not2 = xor i32 %and2, -1 2273 %or = or i32 %not2, %b 2274 %and3 = and i32 %or, %not1 2275 call void @use(i32 %and2) 2276 ret i32 %and3 2277} 2278 2279define i32 @and_or_not_not_2_extra_uses(i32 %a, i32 %b, i32 %c) { 2280; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_2_extra_uses 2281; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2282; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]] 2283; CHECK-NEXT: call void @use(i32 [[AND1]]) 2284; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]] 2285; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1 2286; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOT2]] 2287; CHECK-NEXT: call void @use(i32 [[OR]]) 2288; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND1]], [[OR]] 2289; CHECK-NEXT: ret i32 [[AND3]] 2290; 2291 %and1 = and i32 %b, %a 2292 call void @use(i32 %and1) 2293 %not1 = xor i32 %and1, -1 2294 %and2 = and i32 %a, %c 2295 %not2 = xor i32 %and2, -1 2296 %or = or i32 %not2, %b 2297 call void @use(i32 %or) 2298 %and3 = and i32 %not1, %or 2299 ret i32 %and3 2300} 2301 2302define i32 @and_or_not_not_wrong_a(i32 %a, i32 %b, i32 %c, i32 %d) { 2303; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_wrong_a 2304; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) { 2305; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[D]] 2306; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]] 2307; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1 2308; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOT2]] 2309; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND1]], [[OR]] 2310; CHECK-NEXT: ret i32 [[AND3]] 2311; 2312 %and1 = and i32 %b, %d 2313 %not1 = xor i32 %and1, -1 2314 %and2 = and i32 %a, %c 2315 %not2 = xor i32 %and2, -1 2316 %or = or i32 %not2, %b 2317 %and3 = and i32 %or, %not1 2318 ret i32 %and3 2319} 2320 2321define i32 @and_or_not_not_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) { 2322; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_wrong_b 2323; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) { 2324; CHECK-NEXT: [[AND1:%.*]] = and i32 [[D]], [[A]] 2325; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 2326; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]] 2327; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1 2328; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOT2]] 2329; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR]], [[NOT1]] 2330; CHECK-NEXT: ret i32 [[AND3]] 2331; 2332 %and1 = and i32 %d, %a 2333 %not1 = xor i32 %and1, -1 2334 %and2 = and i32 %a, %c 2335 %not2 = xor i32 %and2, -1 2336 %or = or i32 %not2, %b 2337 %and3 = and i32 %or, %not1 2338 ret i32 %and3 2339} 2340 2341; (a & ~(b | c)) | ~(a | (b ^ c)) --> (~a & b & c) | ~(b | c) 2342 2343define i32 @and_not_or_or_not_or_xor(i32 %a, i32 %b, i32 %c) { 2344; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor 2345; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2346; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]] 2347; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2348; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]] 2349; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]] 2350; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1 2351; CHECK-NEXT: ret i32 [[OR3]] 2352; 2353 %or1 = or i32 %b, %c 2354 %not1 = xor i32 %or1, -1 2355 %and1 = and i32 %not1, %a 2356 %xor1 = xor i32 %b, %c 2357 %or2 = or i32 %xor1, %a 2358 %not2 = xor i32 %or2, -1 2359 %or3 = or i32 %and1, %not2 2360 ret i32 %or3 2361} 2362 2363define i32 @and_not_or_or_not_or_xor_commute1(i32 %a, i32 %b, i32 %c) { 2364; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute1 2365; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2366; CHECK-NEXT: [[OR1:%.*]] = or i32 [[C]], [[B]] 2367; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2368; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]] 2369; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]] 2370; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1 2371; CHECK-NEXT: ret i32 [[OR3]] 2372; 2373 %or1 = or i32 %c, %b 2374 %not1 = xor i32 %or1, -1 2375 %and1 = and i32 %not1, %a 2376 %xor1 = xor i32 %b, %c 2377 %or2 = or i32 %xor1, %a 2378 %not2 = xor i32 %or2, -1 2379 %or3 = or i32 %and1, %not2 2380 ret i32 %or3 2381} 2382 2383define i32 @and_not_or_or_not_or_xor_commute2(i32 %a0, i32 %b, i32 %c) { 2384; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute2 2385; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2386; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 2387; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]] 2388; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2389; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]] 2390; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]] 2391; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1 2392; CHECK-NEXT: ret i32 [[OR3]] 2393; 2394 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 2395 %or1 = or i32 %b, %c 2396 %not1 = xor i32 %or1, -1 2397 %and1 = and i32 %a, %not1 2398 %xor1 = xor i32 %b, %c 2399 %or2 = or i32 %xor1, %a 2400 %not2 = xor i32 %or2, -1 2401 %or3 = or i32 %and1, %not2 2402 ret i32 %or3 2403} 2404 2405define i32 @and_not_or_or_not_or_xor_commute3(i32 %a, i32 %b, i32 %c) { 2406; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute3 2407; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2408; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]] 2409; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[C]], [[B]] 2410; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]] 2411; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]] 2412; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1 2413; CHECK-NEXT: ret i32 [[OR3]] 2414; 2415 %or1 = or i32 %b, %c 2416 %not1 = xor i32 %or1, -1 2417 %and1 = and i32 %not1, %a 2418 %xor1 = xor i32 %c, %b 2419 %or2 = or i32 %xor1, %a 2420 %not2 = xor i32 %or2, -1 2421 %or3 = or i32 %and1, %not2 2422 ret i32 %or3 2423} 2424 2425define i32 @and_not_or_or_not_or_xor_commute4(i32 %a0, i32 %b, i32 %c) { 2426; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute4 2427; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2428; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 2429; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]] 2430; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2431; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[XOR1]] 2432; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]] 2433; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1 2434; CHECK-NEXT: ret i32 [[OR3]] 2435; 2436 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 2437 %or1 = or i32 %b, %c 2438 %not1 = xor i32 %or1, -1 2439 %and1 = and i32 %a, %not1 2440 %xor1 = xor i32 %b, %c 2441 %or2 = or i32 %a, %xor1 2442 %not2 = xor i32 %or2, -1 2443 %or3 = or i32 %and1, %not2 2444 ret i32 %or3 2445} 2446 2447define i32 @and_not_or_or_not_or_xor_commute5(i32 %a, i32 %b, i32 %c) { 2448; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute5 2449; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2450; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]] 2451; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2452; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]] 2453; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]] 2454; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1 2455; CHECK-NEXT: ret i32 [[OR3]] 2456; 2457 %or1 = or i32 %b, %c 2458 %not1 = xor i32 %or1, -1 2459 %and1 = and i32 %not1, %a 2460 %xor1 = xor i32 %b, %c 2461 %or2 = or i32 %xor1, %a 2462 %not2 = xor i32 %or2, -1 2463 %or3 = or i32 %not2, %and1 2464 ret i32 %or3 2465} 2466 2467define i32 @and_not_or_or_not_or_xor_use1(i32 %a, i32 %b, i32 %c) { 2468; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use1 2469; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2470; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]] 2471; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2472; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]] 2473; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]] 2474; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1 2475; CHECK-NEXT: call void @use(i32 [[OR1]]) 2476; CHECK-NEXT: ret i32 [[OR3]] 2477; 2478 %or1 = or i32 %b, %c 2479 %not1 = xor i32 %or1, -1 2480 %and1 = and i32 %not1, %a 2481 %xor1 = xor i32 %b, %c 2482 %or2 = or i32 %xor1, %a 2483 %not2 = xor i32 %or2, -1 2484 %or3 = or i32 %and1, %not2 2485 call void @use(i32 %or1) 2486 ret i32 %or3 2487} 2488 2489define i32 @and_not_or_or_not_or_xor_use2(i32 %a, i32 %b, i32 %c) { 2490; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use2 2491; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2492; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]] 2493; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 2494; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2495; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]] 2496; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]] 2497; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1 2498; CHECK-NEXT: call void @use(i32 [[NOT1]]) 2499; CHECK-NEXT: ret i32 [[OR3]] 2500; 2501 %or1 = or i32 %b, %c 2502 %not1 = xor i32 %or1, -1 2503 %and1 = and i32 %not1, %a 2504 %xor1 = xor i32 %b, %c 2505 %or2 = or i32 %xor1, %a 2506 %not2 = xor i32 %or2, -1 2507 %or3 = or i32 %and1, %not2 2508 call void @use(i32 %not1) 2509 ret i32 %or3 2510} 2511 2512define i32 @and_not_or_or_not_or_xor_use3(i32 %a, i32 %b, i32 %c) { 2513; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use3 2514; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2515; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]] 2516; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 2517; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[NOT1]] 2518; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2519; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]] 2520; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1 2521; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]] 2522; CHECK-NEXT: call void @use(i32 [[AND1]]) 2523; CHECK-NEXT: ret i32 [[OR3]] 2524; 2525 %or1 = or i32 %b, %c 2526 %not1 = xor i32 %or1, -1 2527 %and1 = and i32 %not1, %a 2528 %xor1 = xor i32 %b, %c 2529 %or2 = or i32 %xor1, %a 2530 %not2 = xor i32 %or2, -1 2531 %or3 = or i32 %and1, %not2 2532 call void @use(i32 %and1) 2533 ret i32 %or3 2534} 2535 2536define i32 @and_not_or_or_not_or_xor_use4(i32 %a, i32 %b, i32 %c) { 2537; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use4 2538; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2539; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]] 2540; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2541; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]] 2542; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]] 2543; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1 2544; CHECK-NEXT: call void @use(i32 [[XOR1]]) 2545; CHECK-NEXT: ret i32 [[OR3]] 2546; 2547 %or1 = or i32 %b, %c 2548 %not1 = xor i32 %or1, -1 2549 %and1 = and i32 %not1, %a 2550 %xor1 = xor i32 %b, %c 2551 %or2 = or i32 %xor1, %a 2552 %not2 = xor i32 %or2, -1 2553 %or3 = or i32 %and1, %not2 2554 call void @use(i32 %xor1) 2555 ret i32 %or3 2556} 2557 2558define i32 @and_not_or_or_not_or_xor_use5(i32 %a, i32 %b, i32 %c) { 2559; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use5 2560; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2561; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]] 2562; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2563; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]] 2564; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]] 2565; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1 2566; CHECK-NEXT: call void @use(i32 [[OR2]]) 2567; CHECK-NEXT: ret i32 [[OR3]] 2568; 2569 %or1 = or i32 %b, %c 2570 %not1 = xor i32 %or1, -1 2571 %and1 = and i32 %not1, %a 2572 %xor1 = xor i32 %b, %c 2573 %or2 = or i32 %xor1, %a 2574 %not2 = xor i32 %or2, -1 2575 %or3 = or i32 %and1, %not2 2576 call void @use(i32 %or2) 2577 ret i32 %or3 2578} 2579 2580define i32 @and_not_or_or_not_or_xor_use6(i32 %a, i32 %b, i32 %c) { 2581; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use6 2582; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2583; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]] 2584; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 2585; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[NOT1]] 2586; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2587; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]] 2588; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1 2589; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]] 2590; CHECK-NEXT: call void @use(i32 [[NOT2]]) 2591; CHECK-NEXT: ret i32 [[OR3]] 2592; 2593 %or1 = or i32 %b, %c 2594 %not1 = xor i32 %or1, -1 2595 %and1 = and i32 %not1, %a 2596 %xor1 = xor i32 %b, %c 2597 %or2 = or i32 %xor1, %a 2598 %not2 = xor i32 %or2, -1 2599 %or3 = or i32 %and1, %not2 2600 call void @use(i32 %not2) 2601 ret i32 %or3 2602} 2603 2604; (a | ~(b & c)) & ~(a & (b ^ c)) --> ~(a | b) | (a ^ b ^ c) 2605; This pattern is not handled because the result is more undefined than a source. 2606; It is invalid as is, but feezing %a and %b will make it valid. 2607 2608define i32 @or_not_and_and_not_and_xor(i32 %a, i32 %b, i32 %c) { 2609; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor 2610; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2611; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]] 2612; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 2613; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]] 2614; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2615; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]] 2616; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]] 2617; CHECK-NEXT: ret i32 [[AND3]] 2618; 2619 %and1 = and i32 %b, %c 2620 %not1 = xor i32 %and1, -1 2621 %or1 = or i32 %not1, %a 2622 %xor1 = xor i32 %b, %c 2623 %and2 = and i32 %xor1, %a 2624 %not2 = xor i32 %and2, -1 2625 %and3 = and i32 %or1, %not2 2626 ret i32 %and3 2627} 2628 2629define i32 @or_not_and_and_not_and_xor_commute1(i32 %a, i32 %b, i32 %c) { 2630; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute1 2631; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2632; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C]], [[B]] 2633; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 2634; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]] 2635; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2636; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]] 2637; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]] 2638; CHECK-NEXT: ret i32 [[AND3]] 2639; 2640 %and1 = and i32 %c, %b 2641 %not1 = xor i32 %and1, -1 2642 %or1 = or i32 %not1, %a 2643 %xor1 = xor i32 %b, %c 2644 %and2 = and i32 %xor1, %a 2645 %not2 = xor i32 %and2, -1 2646 %and3 = and i32 %or1, %not2 2647 ret i32 %and3 2648} 2649 2650define i32 @or_not_and_and_not_and_xor_commute2(i32 %a0, i32 %b, i32 %c) { 2651; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute2 2652; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2653; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 2654; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]] 2655; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 2656; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]] 2657; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2658; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]] 2659; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]] 2660; CHECK-NEXT: ret i32 [[AND3]] 2661; 2662 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 2663 %and1 = and i32 %b, %c 2664 %not1 = xor i32 %and1, -1 2665 %or1 = or i32 %a, %not1 2666 %xor1 = xor i32 %b, %c 2667 %and2 = and i32 %xor1, %a 2668 %not2 = xor i32 %and2, -1 2669 %and3 = and i32 %or1, %not2 2670 ret i32 %and3 2671} 2672 2673define i32 @or_not_and_and_not_and_xor_commute3(i32 %a, i32 %b, i32 %c) { 2674; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute3 2675; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2676; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]] 2677; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 2678; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]] 2679; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[C]], [[B]] 2680; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]] 2681; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]] 2682; CHECK-NEXT: ret i32 [[AND3]] 2683; 2684 %and1 = and i32 %b, %c 2685 %not1 = xor i32 %and1, -1 2686 %or1 = or i32 %not1, %a 2687 %xor1 = xor i32 %c, %b 2688 %and2 = and i32 %xor1, %a 2689 %not2 = xor i32 %and2, -1 2690 %and3 = and i32 %or1, %not2 2691 ret i32 %and3 2692} 2693 2694define i32 @or_not_and_and_not_and_xor_commute4(i32 %a0, i32 %b, i32 %c) { 2695; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute4 2696; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2697; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]] 2698; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]] 2699; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 2700; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]] 2701; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2702; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[XOR1]] 2703; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]] 2704; CHECK-NEXT: ret i32 [[AND3]] 2705; 2706 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization 2707 %and1 = and i32 %b, %c 2708 %not1 = xor i32 %and1, -1 2709 %or1 = or i32 %a, %not1 2710 %xor1 = xor i32 %b, %c 2711 %and2 = and i32 %a, %xor1 2712 %not2 = xor i32 %and2, -1 2713 %and3 = and i32 %or1, %not2 2714 ret i32 %and3 2715} 2716 2717define i32 @or_not_and_and_not_and_xor_commute5(i32 %a, i32 %b, i32 %c) { 2718; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute5 2719; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2720; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]] 2721; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 2722; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]] 2723; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2724; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]] 2725; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]] 2726; CHECK-NEXT: ret i32 [[AND3]] 2727; 2728 %and1 = and i32 %b, %c 2729 %not1 = xor i32 %and1, -1 2730 %or1 = or i32 %not1, %a 2731 %xor1 = xor i32 %b, %c 2732 %and2 = and i32 %xor1, %a 2733 %not2 = xor i32 %and2, -1 2734 %and3 = and i32 %not2, %or1 2735 ret i32 %and3 2736} 2737 2738define i32 @or_not_and_and_not_and_xor_use1(i32 %a, i32 %b, i32 %c) { 2739; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use1 2740; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2741; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]] 2742; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 2743; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]] 2744; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2745; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]] 2746; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]] 2747; CHECK-NEXT: call void @use(i32 [[AND1]]) 2748; CHECK-NEXT: ret i32 [[AND3]] 2749; 2750 %and1 = and i32 %b, %c 2751 %not1 = xor i32 %and1, -1 2752 %or1 = or i32 %not1, %a 2753 %xor1 = xor i32 %b, %c 2754 %and2 = and i32 %xor1, %a 2755 %not2 = xor i32 %and2, -1 2756 %and3 = and i32 %or1, %not2 2757 call void @use(i32 %and1) 2758 ret i32 %and3 2759} 2760 2761define i32 @or_not_and_and_not_and_xor_use2(i32 %a, i32 %b, i32 %c) { 2762; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use2 2763; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2764; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]] 2765; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 2766; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]] 2767; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2768; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]] 2769; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]] 2770; CHECK-NEXT: call void @use(i32 [[NOT1]]) 2771; CHECK-NEXT: ret i32 [[AND3]] 2772; 2773 %and1 = and i32 %b, %c 2774 %not1 = xor i32 %and1, -1 2775 %or1 = or i32 %not1, %a 2776 %xor1 = xor i32 %b, %c 2777 %and2 = and i32 %xor1, %a 2778 %not2 = xor i32 %and2, -1 2779 %and3 = and i32 %or1, %not2 2780 call void @use(i32 %not1) 2781 ret i32 %and3 2782} 2783 2784define i32 @or_not_and_and_not_and_xor_use3(i32 %a, i32 %b, i32 %c) { 2785; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use3 2786; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2787; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]] 2788; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 2789; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]] 2790; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2791; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]] 2792; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]] 2793; CHECK-NEXT: call void @use(i32 [[OR1]]) 2794; CHECK-NEXT: ret i32 [[AND3]] 2795; 2796 %and1 = and i32 %b, %c 2797 %not1 = xor i32 %and1, -1 2798 %or1 = or i32 %not1, %a 2799 %xor1 = xor i32 %b, %c 2800 %and2 = and i32 %xor1, %a 2801 %not2 = xor i32 %and2, -1 2802 %and3 = and i32 %or1, %not2 2803 call void @use(i32 %or1) 2804 ret i32 %and3 2805} 2806 2807define i32 @or_not_and_and_not_and_xor_use4(i32 %a, i32 %b, i32 %c) { 2808; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use4 2809; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2810; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]] 2811; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 2812; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]] 2813; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2814; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]] 2815; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]] 2816; CHECK-NEXT: call void @use(i32 [[XOR1]]) 2817; CHECK-NEXT: ret i32 [[AND3]] 2818; 2819 %and1 = and i32 %b, %c 2820 %not1 = xor i32 %and1, -1 2821 %or1 = or i32 %not1, %a 2822 %xor1 = xor i32 %b, %c 2823 %and2 = and i32 %xor1, %a 2824 %not2 = xor i32 %and2, -1 2825 %and3 = and i32 %or1, %not2 2826 call void @use(i32 %xor1) 2827 ret i32 %and3 2828} 2829 2830define i32 @or_not_and_and_not_and_xor_use5(i32 %a, i32 %b, i32 %c) { 2831; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use5 2832; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2833; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]] 2834; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 2835; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]] 2836; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2837; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]] 2838; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]] 2839; CHECK-NEXT: call void @use(i32 [[AND2]]) 2840; CHECK-NEXT: ret i32 [[AND3]] 2841; 2842 %and1 = and i32 %b, %c 2843 %not1 = xor i32 %and1, -1 2844 %or1 = or i32 %not1, %a 2845 %xor1 = xor i32 %b, %c 2846 %and2 = and i32 %xor1, %a 2847 %not2 = xor i32 %and2, -1 2848 %and3 = and i32 %or1, %not2 2849 call void @use(i32 %and2) 2850 ret i32 %and3 2851} 2852 2853define i32 @or_not_and_and_not_and_xor_use6(i32 %a, i32 %b, i32 %c) { 2854; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use6 2855; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2856; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]] 2857; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 2858; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]] 2859; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]] 2860; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]] 2861; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1 2862; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]] 2863; CHECK-NEXT: call void @use(i32 [[NOT2]]) 2864; CHECK-NEXT: ret i32 [[AND3]] 2865; 2866 %and1 = and i32 %b, %c 2867 %not1 = xor i32 %and1, -1 2868 %or1 = or i32 %not1, %a 2869 %xor1 = xor i32 %b, %c 2870 %and2 = and i32 %xor1, %a 2871 %not2 = xor i32 %and2, -1 2872 %and3 = and i32 %or1, %not2 2873 call void @use(i32 %not2) 2874 ret i32 %and3 2875} 2876 2877; (~a & b & c) | ~(a | b | c) -> ~(a | (b ^ c)) 2878 2879define i32 @not_and_and_or_not_or_or(i32 %a, i32 %b, i32 %c) { 2880; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or 2881; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2882; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 2883; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 2884; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 2885; CHECK-NEXT: ret i32 [[OR3]] 2886; 2887 %or1 = or i32 %b, %a 2888 %or2 = or i32 %or1, %c 2889 %not1 = xor i32 %or2, -1 2890 %not2 = xor i32 %a, -1 2891 %and1 = and i32 %not2, %b 2892 %and2 = and i32 %and1, %c 2893 %or3 = or i32 %and2, %not1 2894 ret i32 %or3 2895} 2896 2897define i32 @not_and_and_or_not_or_or_commute1_or(i32 %a, i32 %b, i32 %c) { 2898; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute1_or 2899; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2900; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 2901; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 2902; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 2903; CHECK-NEXT: ret i32 [[OR3]] 2904; 2905 %or1 = or i32 %c, %a 2906 %or2 = or i32 %or1, %b 2907 %not1 = xor i32 %or2, -1 2908 %not2 = xor i32 %a, -1 2909 %and1 = and i32 %not2, %b 2910 %and2 = and i32 %and1, %c 2911 %or3 = or i32 %and2, %not1 2912 ret i32 %or3 2913} 2914 2915define i32 @not_and_and_or_not_or_or_commute2_or(i32 %a, i32 %b, i32 %c) { 2916; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute2_or 2917; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2918; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 2919; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 2920; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 2921; CHECK-NEXT: ret i32 [[OR3]] 2922; 2923 %or1 = or i32 %b, %c 2924 %or2 = or i32 %or1, %a 2925 %not1 = xor i32 %or2, -1 2926 %not2 = xor i32 %a, -1 2927 %and1 = and i32 %not2, %b 2928 %and2 = and i32 %and1, %c 2929 %or3 = or i32 %and2, %not1 2930 ret i32 %or3 2931} 2932 2933define i32 @not_and_and_or_not_or_or_commute1_and(i32 %a, i32 %b, i32 %c) { 2934; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute1_and 2935; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2936; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 2937; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 2938; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 2939; CHECK-NEXT: ret i32 [[OR3]] 2940; 2941 %or1 = or i32 %b, %a 2942 %or2 = or i32 %or1, %c 2943 %not1 = xor i32 %or2, -1 2944 %not2 = xor i32 %a, -1 2945 %and1 = and i32 %not2, %c 2946 %and2 = and i32 %and1, %b 2947 %or3 = or i32 %and2, %not1 2948 ret i32 %or3 2949} 2950 2951define i32 @not_and_and_or_not_or_or_commute2_and(i32 %a, i32 %b, i32 %c) { 2952; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute2_and 2953; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2954; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 2955; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 2956; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 2957; CHECK-NEXT: ret i32 [[OR3]] 2958; 2959 %or1 = or i32 %b, %a 2960 %or2 = or i32 %or1, %c 2961 %not1 = xor i32 %or2, -1 2962 %not2 = xor i32 %a, -1 2963 %and1 = and i32 %b, %c 2964 %and2 = and i32 %and1, %not2 2965 %or3 = or i32 %and2, %not1 2966 ret i32 %or3 2967} 2968 2969define i32 @not_and_and_or_not_or_or_commute1(i32 %a, i32 %b, i32 %c) { 2970; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute1 2971; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 2972; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 2973; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 2974; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 2975; CHECK-NEXT: ret i32 [[OR3]] 2976; 2977 %or1 = or i32 %a, %b 2978 %or2 = or i32 %or1, %c 2979 %not1 = xor i32 %or2, -1 2980 %not2 = xor i32 %a, -1 2981 %and1 = and i32 %not2, %b 2982 %and2 = and i32 %and1, %c 2983 %or3 = or i32 %and2, %not1 2984 ret i32 %or3 2985} 2986 2987define i32 @not_and_and_or_not_or_or_commute2(i32 %a, i32 %b, i32 %c0) { 2988; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute2 2989; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) { 2990; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]] 2991; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 2992; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 2993; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 2994; CHECK-NEXT: ret i32 [[OR3]] 2995; 2996 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization 2997 %or1 = or i32 %b, %a 2998 %or2 = or i32 %c, %or1 2999 %not1 = xor i32 %or2, -1 3000 %not2 = xor i32 %a, -1 3001 %and1 = and i32 %not2, %b 3002 %and2 = and i32 %and1, %c 3003 %or3 = or i32 %and2, %not1 3004 ret i32 %or3 3005} 3006 3007define i32 @not_and_and_or_not_or_or_commute3(i32 %a, i32 %b0, i32 %c) { 3008; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute3 3009; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) { 3010; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 3011; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3012; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 3013; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 3014; CHECK-NEXT: ret i32 [[OR3]] 3015; 3016 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 3017 %or1 = or i32 %b, %a 3018 %or2 = or i32 %or1, %c 3019 %not1 = xor i32 %or2, -1 3020 %not2 = xor i32 %a, -1 3021 %and1 = and i32 %b, %not2 3022 %and2 = and i32 %and1, %c 3023 %or3 = or i32 %and2, %not1 3024 ret i32 %or3 3025} 3026 3027define i32 @not_and_and_or_not_or_or_commute4(i32 %a, i32 %b, i32 %c0) { 3028; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute4 3029; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) { 3030; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]] 3031; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3032; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 3033; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 3034; CHECK-NEXT: ret i32 [[OR3]] 3035; 3036 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization 3037 %or1 = or i32 %b, %a 3038 %or2 = or i32 %or1, %c 3039 %not1 = xor i32 %or2, -1 3040 %not2 = xor i32 %a, -1 3041 %and1 = and i32 %not2, %b 3042 %and2 = and i32 %c, %and1 3043 %or3 = or i32 %and2, %not1 3044 ret i32 %or3 3045} 3046 3047define i32 @not_and_and_or_not_or_or_use1(i32 %a, i32 %b, i32 %c) { 3048; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use1 3049; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3050; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]] 3051; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3052; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 3053; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 3054; CHECK-NEXT: call void @use(i32 [[OR1]]) 3055; CHECK-NEXT: ret i32 [[OR3]] 3056; 3057 %or1 = or i32 %b, %a 3058 %or2 = or i32 %or1, %c 3059 %not1 = xor i32 %or2, -1 3060 %not2 = xor i32 %a, -1 3061 %and1 = and i32 %not2, %b 3062 %and2 = and i32 %and1, %c 3063 %or3 = or i32 %and2, %not1 3064 call void @use(i32 %or1) 3065 ret i32 %or3 3066} 3067 3068define i32 @not_and_and_or_not_or_or_use2(i32 %a, i32 %b, i32 %c) { 3069; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use2 3070; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3071; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]] 3072; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C]] 3073; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3074; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 3075; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 3076; CHECK-NEXT: call void @use(i32 [[OR2]]) 3077; CHECK-NEXT: ret i32 [[OR3]] 3078; 3079 %or1 = or i32 %b, %a 3080 %or2 = or i32 %or1, %c 3081 %not1 = xor i32 %or2, -1 3082 %not2 = xor i32 %a, -1 3083 %and1 = and i32 %not2, %b 3084 %and2 = and i32 %and1, %c 3085 %or3 = or i32 %and2, %not1 3086 call void @use(i32 %or2) 3087 ret i32 %or3 3088} 3089 3090define i32 @not_and_and_or_not_or_or_use3(i32 %a, i32 %b, i32 %c) { 3091; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use3 3092; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3093; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]] 3094; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C]] 3095; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR2]], -1 3096; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3097; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[NOT2]] 3098; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C]] 3099; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND2]], [[NOT1]] 3100; CHECK-NEXT: call void @use(i32 [[NOT1]]) 3101; CHECK-NEXT: ret i32 [[OR3]] 3102; 3103 %or1 = or i32 %b, %a 3104 %or2 = or i32 %or1, %c 3105 %not1 = xor i32 %or2, -1 3106 %not2 = xor i32 %a, -1 3107 %and1 = and i32 %not2, %b 3108 %and2 = and i32 %and1, %c 3109 %or3 = or i32 %and2, %not1 3110 call void @use(i32 %not1) 3111 ret i32 %or3 3112} 3113 3114define i32 @not_and_and_or_not_or_or_use4(i32 %a, i32 %b, i32 %c) { 3115; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use4 3116; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3117; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3118; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3119; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 3120; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 3121; CHECK-NEXT: call void @use(i32 [[NOT2]]) 3122; CHECK-NEXT: ret i32 [[OR3]] 3123; 3124 %or1 = or i32 %b, %a 3125 %or2 = or i32 %or1, %c 3126 %not1 = xor i32 %or2, -1 3127 %not2 = xor i32 %a, -1 3128 %and1 = and i32 %not2, %b 3129 %and2 = and i32 %and1, %c 3130 %or3 = or i32 %and2, %not1 3131 call void @use(i32 %not2) 3132 ret i32 %or3 3133} 3134 3135define i32 @not_and_and_or_not_or_or_use5(i32 %a, i32 %b, i32 %c) { 3136; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use5 3137; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3138; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3139; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[NOT2]] 3140; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3141; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]] 3142; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1 3143; CHECK-NEXT: call void @use(i32 [[AND1]]) 3144; CHECK-NEXT: ret i32 [[OR3]] 3145; 3146 %or1 = or i32 %b, %a 3147 %or2 = or i32 %or1, %c 3148 %not1 = xor i32 %or2, -1 3149 %not2 = xor i32 %a, -1 3150 %and1 = and i32 %not2, %b 3151 %and2 = and i32 %and1, %c 3152 %or3 = or i32 %and2, %not1 3153 call void @use(i32 %and1) 3154 ret i32 %or3 3155} 3156 3157define i32 @not_and_and_or_not_or_or_use6(i32 %a, i32 %b, i32 %c) { 3158; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use6 3159; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3160; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]] 3161; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C]] 3162; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR2]], -1 3163; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3164; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[NOT2]] 3165; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C]] 3166; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND2]], [[NOT1]] 3167; CHECK-NEXT: call void @use(i32 [[AND2]]) 3168; CHECK-NEXT: ret i32 [[OR3]] 3169; 3170 %or1 = or i32 %b, %a 3171 %or2 = or i32 %or1, %c 3172 %not1 = xor i32 %or2, -1 3173 %not2 = xor i32 %a, -1 3174 %and1 = and i32 %not2, %b 3175 %and2 = and i32 %and1, %c 3176 %or3 = or i32 %and2, %not1 3177 call void @use(i32 %and2) 3178 ret i32 %or3 3179} 3180 3181; (~a | b | c) & ~(a & b & c) -> ~a | (b ^ c) 3182 3183define i32 @not_or_or_and_not_and_and(i32 %a, i32 %b, i32 %c) { 3184; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and 3185; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3186; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3187; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3188; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]] 3189; CHECK-NEXT: ret i32 [[AND3]] 3190; 3191 %and1 = and i32 %b, %a 3192 %and2 = and i32 %and1, %c 3193 %not1 = xor i32 %and2, -1 3194 %not2 = xor i32 %a, -1 3195 %or1 = or i32 %not2, %b 3196 %or2 = or i32 %or1, %c 3197 %and3 = and i32 %or2, %not1 3198 ret i32 %and3 3199} 3200 3201define i32 @not_or_or_and_not_and_and_commute1_and(i32 %a, i32 %b, i32 %c) { 3202; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute1_and 3203; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3204; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3205; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3206; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]] 3207; CHECK-NEXT: ret i32 [[AND3]] 3208; 3209 %and1 = and i32 %c, %a 3210 %and2 = and i32 %and1, %b 3211 %not1 = xor i32 %and2, -1 3212 %not2 = xor i32 %a, -1 3213 %or1 = or i32 %not2, %b 3214 %or2 = or i32 %or1, %c 3215 %and3 = and i32 %or2, %not1 3216 ret i32 %and3 3217} 3218 3219define i32 @not_or_or_and_not_and_and_commute2_and(i32 %a, i32 %b, i32 %c) { 3220; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute2_and 3221; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3222; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3223; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3224; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]] 3225; CHECK-NEXT: ret i32 [[AND3]] 3226; 3227 %and1 = and i32 %b, %c 3228 %and2 = and i32 %and1, %a 3229 %not1 = xor i32 %and2, -1 3230 %not2 = xor i32 %a, -1 3231 %or1 = or i32 %not2, %b 3232 %or2 = or i32 %or1, %c 3233 %and3 = and i32 %or2, %not1 3234 ret i32 %and3 3235} 3236 3237define i32 @not_or_or_and_not_and_and_commute1_or(i32 %a, i32 %b, i32 %c) { 3238; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute1_or 3239; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3240; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3241; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 3242; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]] 3243; CHECK-NEXT: ret i32 [[AND3]] 3244; 3245 %and1 = and i32 %b, %a 3246 %and2 = and i32 %and1, %c 3247 %not1 = xor i32 %and2, -1 3248 %not2 = xor i32 %a, -1 3249 %or1 = or i32 %not2, %c 3250 %or2 = or i32 %or1, %b 3251 %and3 = and i32 %or2, %not1 3252 ret i32 %and3 3253} 3254 3255define i32 @not_or_or_and_not_and_and_commute2_or(i32 %a, i32 %b, i32 %c) { 3256; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute2_or 3257; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3258; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3259; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]] 3260; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]] 3261; CHECK-NEXT: ret i32 [[AND3]] 3262; 3263 %and1 = and i32 %b, %a 3264 %and2 = and i32 %and1, %c 3265 %not1 = xor i32 %and2, -1 3266 %not2 = xor i32 %a, -1 3267 %or1 = or i32 %b, %c 3268 %or2 = or i32 %or1, %not2 3269 %and3 = and i32 %or2, %not1 3270 ret i32 %and3 3271} 3272 3273define i32 @not_or_or_and_not_and_and_commute1(i32 %a, i32 %b, i32 %c) { 3274; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute1 3275; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3276; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3277; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3278; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]] 3279; CHECK-NEXT: ret i32 [[AND3]] 3280; 3281 %and1 = and i32 %a, %b 3282 %and2 = and i32 %and1, %c 3283 %not1 = xor i32 %and2, -1 3284 %not2 = xor i32 %a, -1 3285 %or1 = or i32 %not2, %b 3286 %or2 = or i32 %or1, %c 3287 %and3 = and i32 %or2, %not1 3288 ret i32 %and3 3289} 3290 3291define i32 @not_or_or_and_not_and_and_commute2(i32 %a, i32 %b, i32 %c0) { 3292; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute2 3293; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) { 3294; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]] 3295; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3296; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3297; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]] 3298; CHECK-NEXT: ret i32 [[AND3]] 3299; 3300 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization 3301 %and1 = and i32 %b, %a 3302 %and2 = and i32 %c, %and1 3303 %not1 = xor i32 %and2, -1 3304 %not2 = xor i32 %a, -1 3305 %or1 = or i32 %not2, %b 3306 %or2 = or i32 %or1, %c 3307 %and3 = and i32 %or2, %not1 3308 ret i32 %and3 3309} 3310 3311define i32 @not_or_or_and_not_and_and_commute3(i32 %a, i32 %b0, i32 %c) { 3312; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute3 3313; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) { 3314; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 3315; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3316; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3317; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]] 3318; CHECK-NEXT: ret i32 [[AND3]] 3319; 3320 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 3321 %and1 = and i32 %b, %a 3322 %and2 = and i32 %and1, %c 3323 %not1 = xor i32 %and2, -1 3324 %not2 = xor i32 %a, -1 3325 %or1 = or i32 %b, %not2 3326 %or2 = or i32 %or1, %c 3327 %and3 = and i32 %or2, %not1 3328 ret i32 %and3 3329} 3330 3331define i32 @not_or_or_and_not_and_and_commute4(i32 %a, i32 %b, i32 %c0) { 3332; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute4 3333; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) { 3334; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]] 3335; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3336; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3337; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]] 3338; CHECK-NEXT: ret i32 [[AND3]] 3339; 3340 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization 3341 %and1 = and i32 %b, %a 3342 %and2 = and i32 %and1, %c 3343 %not1 = xor i32 %and2, -1 3344 %not2 = xor i32 %a, -1 3345 %or1 = or i32 %not2, %b 3346 %or2 = or i32 %c, %or1 3347 %and3 = and i32 %or2, %not1 3348 ret i32 %and3 3349} 3350 3351define i32 @not_or_or_and_not_and_and_use1(i32 %a, i32 %b, i32 %c) { 3352; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use1 3353; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3354; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]] 3355; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3356; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3357; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]] 3358; CHECK-NEXT: call void @use(i32 [[AND1]]) 3359; CHECK-NEXT: ret i32 [[AND3]] 3360; 3361 %and1 = and i32 %b, %a 3362 %and2 = and i32 %and1, %c 3363 %not1 = xor i32 %and2, -1 3364 %not2 = xor i32 %a, -1 3365 %or1 = or i32 %not2, %b 3366 %or2 = or i32 %or1, %c 3367 %and3 = and i32 %or2, %not1 3368 call void @use(i32 %and1) 3369 ret i32 %and3 3370} 3371 3372define i32 @not_or_or_and_not_and_and_use2(i32 %a, i32 %b, i32 %c) { 3373; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use2 3374; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3375; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]] 3376; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C]] 3377; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3378; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3379; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]] 3380; CHECK-NEXT: call void @use(i32 [[AND2]]) 3381; CHECK-NEXT: ret i32 [[AND3]] 3382; 3383 %and1 = and i32 %b, %a 3384 %and2 = and i32 %and1, %c 3385 %not1 = xor i32 %and2, -1 3386 %not2 = xor i32 %a, -1 3387 %or1 = or i32 %not2, %b 3388 %or2 = or i32 %or1, %c 3389 %and3 = and i32 %or2, %not1 3390 call void @use(i32 %and2) 3391 ret i32 %and3 3392} 3393 3394define i32 @not_or_or_and_not_and_and_use3(i32 %a, i32 %b, i32 %c) { 3395; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use3 3396; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3397; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]] 3398; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C]] 3399; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND2]], -1 3400; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3401; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[NOT2]] 3402; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C]] 3403; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR2]] 3404; CHECK-NEXT: call void @use(i32 [[NOT1]]) 3405; CHECK-NEXT: ret i32 [[AND3]] 3406; 3407 %and1 = and i32 %b, %a 3408 %and2 = and i32 %and1, %c 3409 %not1 = xor i32 %and2, -1 3410 %not2 = xor i32 %a, -1 3411 %or1 = or i32 %not2, %b 3412 %or2 = or i32 %or1, %c 3413 %and3 = and i32 %or2, %not1 3414 call void @use(i32 %not1) 3415 ret i32 %and3 3416} 3417 3418define i32 @not_or_or_and_not_and_and_use4(i32 %a, i32 %b, i32 %c) { 3419; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use4 3420; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3421; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3422; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3423; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]] 3424; CHECK-NEXT: call void @use(i32 [[NOT2]]) 3425; CHECK-NEXT: ret i32 [[AND3]] 3426; 3427 %and1 = and i32 %b, %a 3428 %and2 = and i32 %and1, %c 3429 %not1 = xor i32 %and2, -1 3430 %not2 = xor i32 %a, -1 3431 %or1 = or i32 %not2, %b 3432 %or2 = or i32 %or1, %c 3433 %and3 = and i32 %or2, %not1 3434 call void @use(i32 %not2) 3435 ret i32 %and3 3436} 3437 3438define i32 @not_or_or_and_not_and_and_use5(i32 %a, i32 %b, i32 %c) { 3439; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use5 3440; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3441; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3442; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[NOT2]] 3443; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]] 3444; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]] 3445; CHECK-NEXT: call void @use(i32 [[OR1]]) 3446; CHECK-NEXT: ret i32 [[AND3]] 3447; 3448 %and1 = and i32 %b, %a 3449 %and2 = and i32 %and1, %c 3450 %not1 = xor i32 %and2, -1 3451 %not2 = xor i32 %a, -1 3452 %or1 = or i32 %not2, %b 3453 %or2 = or i32 %or1, %c 3454 %and3 = and i32 %or2, %not1 3455 call void @use(i32 %or1) 3456 ret i32 %and3 3457} 3458 3459define i32 @not_or_or_and_not_and_and_use6(i32 %a, i32 %b, i32 %c) { 3460; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use6 3461; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3462; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]] 3463; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C]] 3464; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3465; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[NOT2]] 3466; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C]] 3467; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR2]] 3468; CHECK-NEXT: call void @use(i32 [[OR2]]) 3469; CHECK-NEXT: ret i32 [[AND3]] 3470; 3471 %and1 = and i32 %b, %a 3472 %and2 = and i32 %and1, %c 3473 %not1 = xor i32 %and2, -1 3474 %not2 = xor i32 %a, -1 3475 %or1 = or i32 %not2, %b 3476 %or2 = or i32 %or1, %c 3477 %and3 = and i32 %or2, %not1 3478 call void @use(i32 %or2) 3479 ret i32 %and3 3480} 3481 3482; (~a & b & c) | ~(a | b) -> (c | ~b) & ~a 3483 3484define i32 @not_and_and_or_no_or(i32 %a, i32 %b, i32 %c) { 3485; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or 3486; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3487; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3488; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3489; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]] 3490; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]] 3491; CHECK-NEXT: ret i32 [[OR2]] 3492; 3493 %or1 = or i32 %b, %a 3494 %not1 = xor i32 %or1, -1 3495 %not2 = xor i32 %a, -1 3496 %and1 = and i32 %not2, %b 3497 %and2 = and i32 %and1, %c 3498 %or2 = or i32 %and2, %not1 3499 ret i32 %or2 3500} 3501 3502define i32 @not_and_and_or_no_or_commute1_and(i32 %a, i32 %b, i32 %c) { 3503; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute1_and 3504; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3505; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3506; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3507; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]] 3508; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]] 3509; CHECK-NEXT: ret i32 [[OR2]] 3510; 3511 %or1 = or i32 %b, %a 3512 %not1 = xor i32 %or1, -1 3513 %not2 = xor i32 %a, -1 3514 %and1 = and i32 %c, %b 3515 %and2 = and i32 %and1, %not2 3516 %or2 = or i32 %and2, %not1 3517 ret i32 %or2 3518} 3519 3520define i32 @not_and_and_or_no_or_commute2_and(i32 %a, i32 %b, i32 %c) { 3521; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute2_and 3522; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3523; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3524; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3525; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]] 3526; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]] 3527; CHECK-NEXT: ret i32 [[OR2]] 3528; 3529 %or1 = or i32 %b, %a 3530 %not1 = xor i32 %or1, -1 3531 %not2 = xor i32 %a, -1 3532 %and1 = and i32 %not2, %c 3533 %and2 = and i32 %and1, %b 3534 %or2 = or i32 %and2, %not1 3535 ret i32 %or2 3536} 3537 3538define i32 @not_and_and_or_no_or_commute1(i32 %a, i32 %b, i32 %c) { 3539; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute1 3540; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3541; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3542; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3543; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]] 3544; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]] 3545; CHECK-NEXT: ret i32 [[OR2]] 3546; 3547 %or1 = or i32 %a, %b 3548 %not1 = xor i32 %or1, -1 3549 %not2 = xor i32 %a, -1 3550 %and1 = and i32 %not2, %b 3551 %and2 = and i32 %and1, %c 3552 %or2 = or i32 %and2, %not1 3553 ret i32 %or2 3554} 3555 3556define i32 @not_and_and_or_no_or_commute2(i32 %a, i32 %b0, i32 %c) { 3557; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute2 3558; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) { 3559; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 3560; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3561; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3562; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]] 3563; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]] 3564; CHECK-NEXT: ret i32 [[OR2]] 3565; 3566 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 3567 %or1 = or i32 %b, %a 3568 %not1 = xor i32 %or1, -1 3569 %not2 = xor i32 %a, -1 3570 %and1 = and i32 %b, %not2 3571 %and2 = and i32 %and1, %c 3572 %or2 = or i32 %and2, %not1 3573 ret i32 %or2 3574} 3575 3576define i32 @not_and_and_or_no_or_commute3(i32 %a, i32 %b, i32 %c0) { 3577; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute3 3578; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) { 3579; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]] 3580; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3581; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3582; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]] 3583; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]] 3584; CHECK-NEXT: ret i32 [[OR2]] 3585; 3586 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization 3587 %or1 = or i32 %b, %a 3588 %not1 = xor i32 %or1, -1 3589 %not2 = xor i32 %a, -1 3590 %and1 = and i32 %not2, %b 3591 %and2 = and i32 %c, %and1 3592 %or2 = or i32 %and2, %not1 3593 ret i32 %or2 3594} 3595 3596define i32 @not_and_and_or_no_or_use1(i32 %a, i32 %b, i32 %c) { 3597; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use1 3598; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3599; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3600; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3601; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]] 3602; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]] 3603; CHECK-NEXT: call void @use(i32 [[NOT2]]) 3604; CHECK-NEXT: ret i32 [[OR2]] 3605; 3606 %or1 = or i32 %b, %a 3607 %not1 = xor i32 %or1, -1 3608 %not2 = xor i32 %a, -1 3609 %and1 = and i32 %not2, %b 3610 %and2 = and i32 %and1, %c 3611 %or2 = or i32 %and2, %not1 3612 call void @use(i32 %not2) 3613 ret i32 %or2 3614} 3615 3616define i32 @not_and_and_or_no_or_use2(i32 %a, i32 %b, i32 %c) { 3617; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use2 3618; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3619; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3620; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3621; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]] 3622; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]] 3623; CHECK-NEXT: call void @use(i32 [[NOT2]]) 3624; CHECK-NEXT: ret i32 [[OR2]] 3625; 3626 %or1 = or i32 %b, %a 3627 %not1 = xor i32 %or1, -1 3628 %not2 = xor i32 %a, -1 3629 %and1 = and i32 %b, %c 3630 %and2 = and i32 %and1, %not2 3631 %or2 = or i32 %and2, %not1 3632 call void @use(i32 %not2) 3633 ret i32 %or2 3634} 3635 3636define i32 @not_and_and_or_no_or_use3(i32 %a, i32 %b, i32 %c) { 3637; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use3 3638; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3639; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3640; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3641; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]] 3642; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]] 3643; CHECK-NEXT: call void @use(i32 [[NOT2]]) 3644; CHECK-NEXT: ret i32 [[OR2]] 3645; 3646 %or1 = or i32 %b, %a 3647 %not1 = xor i32 %or1, -1 3648 %not2 = xor i32 %a, -1 3649 %and1 = and i32 %not2, %c 3650 %and2 = and i32 %and1, %b 3651 %or2 = or i32 %and2, %not1 3652 call void @use(i32 %not2) 3653 ret i32 %or2 3654} 3655 3656define i32 @not_and_and_or_no_or_use4(i32 %a, i32 %b, i32 %c) { 3657; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use4 3658; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3659; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3660; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3661; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]] 3662; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]] 3663; CHECK-NEXT: call void @use(i32 [[NOT2]]) 3664; CHECK-NEXT: ret i32 [[OR2]] 3665; 3666 %or1 = or i32 %b, %a 3667 %not1 = xor i32 %or1, -1 3668 %not2 = xor i32 %a, -1 3669 %and1 = and i32 %not2, %c 3670 %and2 = and i32 %and1, %b 3671 %or2 = or i32 %and2, %not1 3672 call void @use(i32 %not2) 3673 ret i32 %or2 3674} 3675 3676define i32 @not_and_and_or_no_or_use5(i32 %a, i32 %b, i32 %c) { 3677; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use5 3678; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3679; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]] 3680; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 3681; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3682; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[NOT2]] 3683; CHECK-NEXT: [[AND2:%.*]] = and i32 [[TMP1]], [[B]] 3684; CHECK-NEXT: [[OR2:%.*]] = or i32 [[AND2]], [[NOT1]] 3685; CHECK-NEXT: call void @use(i32 [[OR1]]) 3686; CHECK-NEXT: ret i32 [[OR2]] 3687; 3688 %or1 = or i32 %b, %a 3689 %not1 = xor i32 %or1, -1 3690 %not2 = xor i32 %a, -1 3691 %and1 = and i32 %not2, %b 3692 %and2 = and i32 %and1, %c 3693 %or2 = or i32 %and2, %not1 3694 call void @use(i32 %or1) 3695 ret i32 %or2 3696} 3697 3698define i32 @not_and_and_or_no_or_use6(i32 %a, i32 %b, i32 %c) { 3699; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use6 3700; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3701; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]] 3702; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 3703; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3704; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[NOT2]] 3705; CHECK-NEXT: [[AND2:%.*]] = and i32 [[TMP1]], [[B]] 3706; CHECK-NEXT: [[OR2:%.*]] = or i32 [[AND2]], [[NOT1]] 3707; CHECK-NEXT: call void @use(i32 [[NOT1]]) 3708; CHECK-NEXT: ret i32 [[OR2]] 3709; 3710 %or1 = or i32 %b, %a 3711 %not1 = xor i32 %or1, -1 3712 %not2 = xor i32 %a, -1 3713 %and1 = and i32 %not2, %b 3714 %and2 = and i32 %and1, %c 3715 %or2 = or i32 %and2, %not1 3716 call void @use(i32 %not1) 3717 ret i32 %or2 3718} 3719 3720define i32 @not_and_and_or_no_or_use7(i32 %a, i32 %b, i32 %c) { 3721; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use7 3722; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3723; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3724; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[NOT2]] 3725; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3726; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]] 3727; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]] 3728; CHECK-NEXT: call void @use(i32 [[AND1]]) 3729; CHECK-NEXT: ret i32 [[OR2]] 3730; 3731 %or1 = or i32 %b, %a 3732 %not1 = xor i32 %or1, -1 3733 %not2 = xor i32 %a, -1 3734 %and1 = and i32 %not2, %b 3735 %and2 = and i32 %and1, %c 3736 %or2 = or i32 %and2, %not1 3737 call void @use(i32 %and1) 3738 ret i32 %or2 3739} 3740 3741define i32 @not_and_and_or_no_or_use8(i32 %a, i32 %b, i32 %c) { 3742; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use8 3743; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3744; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]] 3745; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1 3746; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3747; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[NOT2]] 3748; CHECK-NEXT: [[AND2:%.*]] = and i32 [[TMP1]], [[B]] 3749; CHECK-NEXT: [[OR2:%.*]] = or i32 [[AND2]], [[NOT1]] 3750; CHECK-NEXT: call void @use(i32 [[AND2]]) 3751; CHECK-NEXT: ret i32 [[OR2]] 3752; 3753 %or1 = or i32 %b, %a 3754 %not1 = xor i32 %or1, -1 3755 %not2 = xor i32 %a, -1 3756 %and1 = and i32 %not2, %b 3757 %and2 = and i32 %and1, %c 3758 %or2 = or i32 %and2, %not1 3759 call void @use(i32 %and2) 3760 ret i32 %or2 3761} 3762 3763; (~a | b | c) & ~(a & b) -> (c & ~b) | ~a 3764 3765define i32 @not_or_or_and_no_and(i32 %a, i32 %b, i32 %c) { 3766; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and 3767; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3768; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3769; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3770; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]] 3771; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]] 3772; CHECK-NEXT: ret i32 [[AND2]] 3773; 3774 %and1 = and i32 %b, %a 3775 %not1 = xor i32 %and1, -1 3776 %not2 = xor i32 %a, -1 3777 %or1 = or i32 %not2, %b 3778 %or2 = or i32 %or1, %c 3779 %and2 = and i32 %or2, %not1 3780 ret i32 %and2 3781} 3782 3783define i32 @not_or_or_and_no_and_commute1_or(i32 %a, i32 %b, i32 %c) { 3784; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute1_or 3785; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3786; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3787; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3788; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]] 3789; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]] 3790; CHECK-NEXT: ret i32 [[AND2]] 3791; 3792 %and1 = and i32 %b, %a 3793 %not1 = xor i32 %and1, -1 3794 %not2 = xor i32 %a, -1 3795 %or1 = or i32 %c, %b 3796 %or2 = or i32 %or1, %not2 3797 %and2 = and i32 %or2, %not1 3798 ret i32 %and2 3799} 3800 3801define i32 @not_or_or_and_no_and_commute2_or(i32 %a, i32 %b, i32 %c) { 3802; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute2_or 3803; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3804; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3805; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3806; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]] 3807; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]] 3808; CHECK-NEXT: ret i32 [[AND2]] 3809; 3810 %and1 = and i32 %b, %a 3811 %not1 = xor i32 %and1, -1 3812 %not2 = xor i32 %a, -1 3813 %or1 = or i32 %not2, %c 3814 %or2 = or i32 %or1, %b 3815 %and2 = and i32 %or2, %not1 3816 ret i32 %and2 3817} 3818 3819define i32 @not_or_or_and_no_and_commute1(i32 %a, i32 %b, i32 %c) { 3820; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute1 3821; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3822; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3823; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3824; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]] 3825; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]] 3826; CHECK-NEXT: ret i32 [[AND2]] 3827; 3828 %and1 = and i32 %a, %b 3829 %not1 = xor i32 %and1, -1 3830 %not2 = xor i32 %a, -1 3831 %or1 = or i32 %not2, %b 3832 %or2 = or i32 %or1, %c 3833 %and2 = and i32 %or2, %not1 3834 ret i32 %and2 3835} 3836 3837define i32 @not_or_or_and_no_and_commute2(i32 %a, i32 %b0, i32 %c) { 3838; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute2 3839; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) { 3840; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]] 3841; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3842; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3843; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]] 3844; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]] 3845; CHECK-NEXT: ret i32 [[AND2]] 3846; 3847 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization 3848 %and1 = and i32 %b, %a 3849 %not1 = xor i32 %and1, -1 3850 %not2 = xor i32 %a, -1 3851 %or1 = or i32 %b, %not2 3852 %or2 = or i32 %or1, %c 3853 %and2 = and i32 %or2, %not1 3854 ret i32 %and2 3855} 3856 3857define i32 @not_or_or_and_no_and_commute3(i32 %a, i32 %b, i32 %c0) { 3858; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute3 3859; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) { 3860; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]] 3861; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3862; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3863; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]] 3864; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]] 3865; CHECK-NEXT: ret i32 [[AND2]] 3866; 3867 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization 3868 %and1 = and i32 %b, %a 3869 %not1 = xor i32 %and1, -1 3870 %not2 = xor i32 %a, -1 3871 %or1 = or i32 %not2, %b 3872 %or2 = or i32 %c, %or1 3873 %and2 = and i32 %or2, %not1 3874 ret i32 %and2 3875} 3876 3877define i32 @not_or_or_and_no_and_use1(i32 %a, i32 %b, i32 %c) { 3878; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use1 3879; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3880; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3881; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3882; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]] 3883; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]] 3884; CHECK-NEXT: call void @use(i32 [[NOT2]]) 3885; CHECK-NEXT: ret i32 [[AND2]] 3886; 3887 %and1 = and i32 %b, %a 3888 %not1 = xor i32 %and1, -1 3889 %not2 = xor i32 %a, -1 3890 %or1 = or i32 %not2, %b 3891 %or2 = or i32 %or1, %c 3892 %and2 = and i32 %or2, %not1 3893 call void @use(i32 %not2) 3894 ret i32 %and2 3895} 3896 3897define i32 @not_or_or_and_no_and_use2(i32 %a, i32 %b, i32 %c) { 3898; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use2 3899; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3900; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3901; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3902; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]] 3903; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]] 3904; CHECK-NEXT: call void @use(i32 [[NOT2]]) 3905; CHECK-NEXT: ret i32 [[AND2]] 3906; 3907 %and1 = and i32 %b, %a 3908 %not1 = xor i32 %and1, -1 3909 %not2 = xor i32 %a, -1 3910 %or1 = or i32 %b, %c 3911 %or2 = or i32 %or1, %not2 3912 %and2 = and i32 %or2, %not1 3913 call void @use(i32 %not2) 3914 ret i32 %and2 3915} 3916 3917define i32 @not_or_or_and_no_and_use3(i32 %a, i32 %b, i32 %c) { 3918; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use3 3919; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3920; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3921; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3922; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]] 3923; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]] 3924; CHECK-NEXT: call void @use(i32 [[NOT2]]) 3925; CHECK-NEXT: ret i32 [[AND2]] 3926; 3927 %and1 = and i32 %b, %a 3928 %not1 = xor i32 %and1, -1 3929 %not2 = xor i32 %a, -1 3930 %or1 = or i32 %not2, %c 3931 %or2 = or i32 %or1, %b 3932 %and2 = and i32 %or2, %not1 3933 call void @use(i32 %not2) 3934 ret i32 %and2 3935} 3936 3937define i32 @not_or_or_and_no_and_use4(i32 %a, i32 %b, i32 %c) { 3938; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use4 3939; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3940; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3941; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 3942; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]] 3943; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]] 3944; CHECK-NEXT: call void @use(i32 [[NOT2]]) 3945; CHECK-NEXT: ret i32 [[AND2]] 3946; 3947 %and1 = and i32 %b, %a 3948 %not1 = xor i32 %and1, -1 3949 %not2 = xor i32 %a, -1 3950 %or1 = or i32 %not2, %c 3951 %or2 = or i32 %or1, %b 3952 %and2 = and i32 %or2, %not1 3953 call void @use(i32 %not2) 3954 ret i32 %and2 3955} 3956 3957define i32 @not_or_or_and_no_and_use5(i32 %a, i32 %b, i32 %c) { 3958; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use5 3959; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3960; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]] 3961; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3962; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[NOT2]] 3963; CHECK-NEXT: [[OR2:%.*]] = or i32 [[TMP1]], [[B]] 3964; CHECK-NEXT: [[AND2:%.*]] = xor i32 [[AND1]], [[OR2]] 3965; CHECK-NEXT: call void @use(i32 [[AND1]]) 3966; CHECK-NEXT: ret i32 [[AND2]] 3967; 3968 %and1 = and i32 %b, %a 3969 %not1 = xor i32 %and1, -1 3970 %not2 = xor i32 %a, -1 3971 %or1 = or i32 %not2, %b 3972 %or2 = or i32 %or1, %c 3973 %and2 = and i32 %or2, %not1 3974 call void @use(i32 %and1) 3975 ret i32 %and2 3976} 3977 3978define i32 @not_or_or_and_no_and_use6(i32 %a, i32 %b, i32 %c) { 3979; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use6 3980; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 3981; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]] 3982; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1 3983; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 3984; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[NOT2]] 3985; CHECK-NEXT: [[OR2:%.*]] = or i32 [[TMP1]], [[B]] 3986; CHECK-NEXT: [[AND2:%.*]] = xor i32 [[AND1]], [[OR2]] 3987; CHECK-NEXT: call void @use(i32 [[NOT1]]) 3988; CHECK-NEXT: ret i32 [[AND2]] 3989; 3990 %and1 = and i32 %b, %a 3991 %not1 = xor i32 %and1, -1 3992 %not2 = xor i32 %a, -1 3993 %or1 = or i32 %not2, %b 3994 %or2 = or i32 %or1, %c 3995 %and2 = and i32 %or2, %not1 3996 call void @use(i32 %not1) 3997 ret i32 %and2 3998} 3999 4000define i32 @not_or_or_and_no_and_use7(i32 %a, i32 %b, i32 %c) { 4001; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use7 4002; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 4003; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 4004; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[NOT2]] 4005; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 4006; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]] 4007; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]] 4008; CHECK-NEXT: call void @use(i32 [[OR1]]) 4009; CHECK-NEXT: ret i32 [[AND2]] 4010; 4011 %and1 = and i32 %b, %a 4012 %not1 = xor i32 %and1, -1 4013 %not2 = xor i32 %a, -1 4014 %or1 = or i32 %not2, %b 4015 %or2 = or i32 %or1, %c 4016 %and2 = and i32 %or2, %not1 4017 call void @use(i32 %or1) 4018 ret i32 %and2 4019} 4020 4021define i32 @not_or_or_and_no_and_use8(i32 %a, i32 %b, i32 %c) { 4022; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use8 4023; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { 4024; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]] 4025; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1 4026; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[NOT2]] 4027; CHECK-NEXT: [[OR2:%.*]] = or i32 [[TMP1]], [[B]] 4028; CHECK-NEXT: [[AND2:%.*]] = xor i32 [[AND1]], [[OR2]] 4029; CHECK-NEXT: call void @use(i32 [[OR2]]) 4030; CHECK-NEXT: ret i32 [[AND2]] 4031; 4032 %and1 = and i32 %b, %a 4033 %not1 = xor i32 %and1, -1 4034 %not2 = xor i32 %a, -1 4035 %or1 = or i32 %not2, %b 4036 %or2 = or i32 %or1, %c 4037 %and2 = and i32 %or2, %not1 4038 call void @use(i32 %or2) 4039 ret i32 %and2 4040} 4041 4042define i4 @and_orn_xor(i4 %a, i4 %b) { 4043; CHECK-LABEL: define {{[^@]+}}@and_orn_xor 4044; CHECK-SAME: (i4 [[A:%.*]], i4 [[B:%.*]]) { 4045; CHECK-NEXT: [[TMP1:%.*]] = xor i4 [[A]], -1 4046; CHECK-NEXT: [[R:%.*]] = and i4 [[B]], [[TMP1]] 4047; CHECK-NEXT: ret i4 [[R]] 4048; 4049 %xor = xor i4 %a, %b 4050 %nota = xor i4 %a, -1 4051 %or = or i4 %nota, %b 4052 %r = and i4 %or, %xor 4053 ret i4 %r 4054} 4055 4056define <2 x i4> @and_orn_xor_commute1(<2 x i4> %a, <2 x i4> %b) { 4057; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute1 4058; CHECK-SAME: (<2 x i4> [[A:%.*]], <2 x i4> [[B:%.*]]) { 4059; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i4> [[A]], splat (i4 -1) 4060; CHECK-NEXT: [[R:%.*]] = and <2 x i4> [[B]], [[TMP1]] 4061; CHECK-NEXT: ret <2 x i4> [[R]] 4062; 4063 %xor = xor <2 x i4> %a, %b 4064 %nota = xor <2 x i4> %a, <i4 -1, i4 poison> 4065 %or = or <2 x i4> %nota, %b 4066 %r = and <2 x i4> %xor, %or 4067 ret <2 x i4> %r 4068} 4069 4070define i32 @and_orn_xor_commute2(i32 %a, i32 %b) { 4071; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute2 4072; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) { 4073; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[A]] 4074; CHECK-NEXT: call void @use(i32 [[XOR]]) 4075; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -1 4076; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]] 4077; CHECK-NEXT: ret i32 [[R]] 4078; 4079 %xor = xor i32 %b, %a 4080 call void @use(i32 %xor) 4081 %nota = xor i32 %a, -1 4082 %or = or i32 %nota, %b 4083 %r = and i32 %or, %xor 4084 ret i32 %r 4085} 4086 4087define i32 @and_orn_xor_commute3(i32 %a, i32 %b) { 4088; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute3 4089; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) { 4090; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1 4091; CHECK-NEXT: call void @use(i32 [[NOTA]]) 4092; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -1 4093; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]] 4094; CHECK-NEXT: ret i32 [[R]] 4095; 4096 %xor = xor i32 %b, %a 4097 %nota = xor i32 %a, -1 4098 call void @use(i32 %nota) 4099 %or = or i32 %nota, %b 4100 %r = and i32 %xor, %or 4101 ret i32 %r 4102} 4103 4104define i32 @and_orn_xor_commute5(i32 %pa, i32 %pb) { 4105; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute5 4106; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) { 4107; CHECK-NEXT: [[A:%.*]] = mul i32 [[PA]], [[PA]] 4108; CHECK-NEXT: [[B:%.*]] = mul i32 [[PB]], [[PB]] 4109; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1 4110; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOTA]] 4111; CHECK-NEXT: call void @use(i32 [[OR]]) 4112; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -1 4113; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]] 4114; CHECK-NEXT: ret i32 [[R]] 4115; 4116 %a = mul i32 %pa, %pa 4117 %b = mul i32 %pb, %pb 4118 %xor = xor i32 %a, %b 4119 %nota = xor i32 %a, -1 4120 %or = or i32 %b, %nota 4121 call void @use(i32 %or) 4122 %r = and i32 %or, %xor 4123 ret i32 %r 4124} 4125 4126define i32 @and_orn_xor_commute6(i32 %pa, i32 %pb) { 4127; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute6 4128; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) { 4129; CHECK-NEXT: [[A:%.*]] = mul i32 [[PA]], [[PA]] 4130; CHECK-NEXT: [[B:%.*]] = mul i32 [[PB]], [[PB]] 4131; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]] 4132; CHECK-NEXT: call void @use(i32 [[XOR]]) 4133; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1 4134; CHECK-NEXT: call void @use(i32 [[NOTA]]) 4135; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -1 4136; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]] 4137; CHECK-NEXT: ret i32 [[R]] 4138; 4139 %a = mul i32 %pa, %pa 4140 %b = mul i32 %pb, %pb 4141 %xor = xor i32 %a, %b 4142 call void @use(i32 %xor) 4143 %nota = xor i32 %a, -1 4144 call void @use(i32 %nota) 4145 %or = or i32 %b, %nota 4146 %r = and i32 %xor, %or 4147 ret i32 %r 4148} 4149 4150define i32 @and_orn_xor_commute7(i32 %pa, i32 %pb) { 4151; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute7 4152; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) { 4153; CHECK-NEXT: [[A:%.*]] = mul i32 [[PA]], [[PA]] 4154; CHECK-NEXT: [[B:%.*]] = mul i32 [[PB]], [[PB]] 4155; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[A]] 4156; CHECK-NEXT: call void @use(i32 [[XOR]]) 4157; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1 4158; CHECK-NEXT: call void @use(i32 [[NOTA]]) 4159; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOTA]] 4160; CHECK-NEXT: call void @use(i32 [[OR]]) 4161; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -1 4162; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]] 4163; CHECK-NEXT: ret i32 [[R]] 4164; 4165 %a = mul i32 %pa, %pa 4166 %b = mul i32 %pb, %pb 4167 %xor = xor i32 %b, %a 4168 call void @use(i32 %xor) 4169 %nota = xor i32 %a, -1 4170 call void @use(i32 %nota) 4171 %or = or i32 %b, %nota 4172 call void @use(i32 %or) 4173 %r = and i32 %or, %xor 4174 ret i32 %r 4175} 4176 4177define i32 @and_orn_xor_commute8(i32 %pa, i32 %pb) { 4178; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute8 4179; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) { 4180; CHECK-NEXT: [[A:%.*]] = mul i32 [[PA]], [[PA]] 4181; CHECK-NEXT: [[B:%.*]] = mul i32 [[PB]], [[PB]] 4182; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -1 4183; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]] 4184; CHECK-NEXT: ret i32 [[R]] 4185; 4186 %a = mul i32 %pa, %pa 4187 %b = mul i32 %pb, %pb 4188 %xor = xor i32 %b, %a 4189 %nota = xor i32 %a, -1 4190 %or = or i32 %b, %nota 4191 %r = and i32 %xor, %or 4192 ret i32 %r 4193} 4194 4195define i32 @zext_zext_and_uses(i8 %x, i8 %y) { 4196; CHECK-LABEL: define {{[^@]+}}@zext_zext_and_uses 4197; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) { 4198; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X]] to i32 4199; CHECK-NEXT: call void @use(i32 [[ZX]]) 4200; CHECK-NEXT: [[ZY:%.*]] = zext i8 [[Y]] to i32 4201; CHECK-NEXT: call void @use(i32 [[ZY]]) 4202; CHECK-NEXT: [[R:%.*]] = and i32 [[ZX]], [[ZY]] 4203; CHECK-NEXT: ret i32 [[R]] 4204; 4205 %zx = zext i8 %x to i32 4206 call void @use(i32 %zx) 4207 %zy = zext i8 %y to i32 4208 call void @use(i32 %zy) 4209 %r = and i32 %zx, %zy 4210 ret i32 %r 4211} 4212 4213define i32 @sext_sext_or_uses(i8 %x, i8 %y) { 4214; CHECK-LABEL: define {{[^@]+}}@sext_sext_or_uses 4215; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) { 4216; CHECK-NEXT: [[SX:%.*]] = sext i8 [[X]] to i32 4217; CHECK-NEXT: call void @use(i32 [[SX]]) 4218; CHECK-NEXT: [[SY:%.*]] = sext i8 [[Y]] to i32 4219; CHECK-NEXT: call void @use(i32 [[SY]]) 4220; CHECK-NEXT: [[R:%.*]] = or i32 [[SX]], [[SY]] 4221; CHECK-NEXT: ret i32 [[R]] 4222; 4223 %sx = sext i8 %x to i32 4224 call void @use(i32 %sx) 4225 %sy = sext i8 %y to i32 4226 call void @use(i32 %sy) 4227 %r = or i32 %sx, %sy 4228 ret i32 %r 4229} 4230 4231define i32 @trunc_trunc_xor_uses(i65 %x, i65 %y) { 4232; CHECK-LABEL: define {{[^@]+}}@trunc_trunc_xor_uses 4233; CHECK-SAME: (i65 [[X:%.*]], i65 [[Y:%.*]]) { 4234; CHECK-NEXT: [[SX:%.*]] = trunc i65 [[X]] to i32 4235; CHECK-NEXT: call void @use(i32 [[SX]]) 4236; CHECK-NEXT: [[SY:%.*]] = trunc i65 [[Y]] to i32 4237; CHECK-NEXT: call void @use(i32 [[SY]]) 4238; CHECK-NEXT: [[R:%.*]] = xor i32 [[SX]], [[SY]] 4239; CHECK-NEXT: ret i32 [[R]] 4240; 4241 %sx = trunc i65 %x to i32 4242 call void @use(i32 %sx) 4243 %sy = trunc i65 %y to i32 4244 call void @use(i32 %sy) 4245 %r = xor i32 %sx, %sy 4246 ret i32 %r 4247} 4248 4249define i16 @and_zext_zext(i8 %x, i4 %y) { 4250; CHECK-LABEL: define {{[^@]+}}@and_zext_zext 4251; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) { 4252; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[Y]] to i8 4253; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X]], [[TMP1]] 4254; CHECK-NEXT: [[R:%.*]] = zext nneg i8 [[TMP2]] to i16 4255; CHECK-NEXT: ret i16 [[R]] 4256; 4257 %zx = zext i8 %x to i16 4258 %zy = zext i4 %y to i16 4259 %r = and i16 %zx, %zy 4260 ret i16 %r 4261} 4262 4263define i16 @or_zext_zext(i8 %x, i4 %y) { 4264; CHECK-LABEL: define {{[^@]+}}@or_zext_zext 4265; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) { 4266; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[Y]] to i8 4267; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[X]], [[TMP1]] 4268; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16 4269; CHECK-NEXT: ret i16 [[R]] 4270; 4271 %zx = zext i8 %x to i16 4272 %zy = zext i4 %y to i16 4273 %r = or i16 %zy, %zx 4274 ret i16 %r 4275} 4276 4277define <2 x i16> @xor_zext_zext(<2 x i8> %x, <2 x i4> %y) { 4278; CHECK-LABEL: define {{[^@]+}}@xor_zext_zext 4279; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i4> [[Y:%.*]]) { 4280; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i4> [[Y]] to <2 x i8> 4281; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i8> [[X]], [[TMP1]] 4282; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16> 4283; CHECK-NEXT: ret <2 x i16> [[R]] 4284; 4285 %zx = zext <2 x i8> %x to <2 x i16> 4286 %zy = zext <2 x i4> %y to <2 x i16> 4287 %r = xor <2 x i16> %zx, %zy 4288 ret <2 x i16> %r 4289} 4290 4291define i16 @and_sext_sext(i8 %x, i4 %y) { 4292; CHECK-LABEL: define {{[^@]+}}@and_sext_sext 4293; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) { 4294; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y]] to i8 4295; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X]], [[TMP1]] 4296; CHECK-NEXT: [[R:%.*]] = sext i8 [[TMP2]] to i16 4297; CHECK-NEXT: ret i16 [[R]] 4298; 4299 %sx = sext i8 %x to i16 4300 %sy = sext i4 %y to i16 4301 %r = and i16 %sy, %sx 4302 ret i16 %r 4303} 4304 4305define i16 @or_sext_sext(i8 %x, i4 %y) { 4306; CHECK-LABEL: define {{[^@]+}}@or_sext_sext 4307; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) { 4308; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y]] to i8 4309; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[X]], [[TMP1]] 4310; CHECK-NEXT: [[R:%.*]] = sext i8 [[TMP2]] to i16 4311; CHECK-NEXT: ret i16 [[R]] 4312; 4313 %sx = sext i8 %x to i16 4314 %sy = sext i4 %y to i16 4315 %r = or i16 %sx, %sy 4316 ret i16 %r 4317} 4318 4319define i16 @xor_sext_sext(i8 %x, i4 %y) { 4320; CHECK-LABEL: define {{[^@]+}}@xor_sext_sext 4321; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) { 4322; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y]] to i8 4323; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[X]], [[TMP1]] 4324; CHECK-NEXT: [[R:%.*]] = sext i8 [[TMP2]] to i16 4325; CHECK-NEXT: ret i16 [[R]] 4326; 4327 %sx = sext i8 %x to i16 4328 %sy = sext i4 %y to i16 4329 %r = xor i16 %sx, %sy 4330 ret i16 %r 4331} 4332 4333; negative test - mismatched casts 4334 4335define i16 @and_zext_sext(i8 %x, i4 %y) { 4336; CHECK-LABEL: define {{[^@]+}}@and_zext_sext 4337; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) { 4338; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X]] to i16 4339; CHECK-NEXT: [[SY:%.*]] = sext i4 [[Y]] to i16 4340; CHECK-NEXT: [[R:%.*]] = and i16 [[ZX]], [[SY]] 4341; CHECK-NEXT: ret i16 [[R]] 4342; 4343 %zx = zext i8 %x to i16 4344 %sy = sext i4 %y to i16 4345 %r = and i16 %zx, %sy 4346 ret i16 %r 4347} 4348 4349; negative test - don't create an extra instruction 4350 4351define i32 @and_zext_zext_use1(i8 %x, i4 %y) { 4352; CHECK-LABEL: define {{[^@]+}}@and_zext_zext_use1 4353; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) { 4354; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X]] to i32 4355; CHECK-NEXT: call void @use(i32 [[ZX]]) 4356; CHECK-NEXT: [[ZY:%.*]] = zext i4 [[Y]] to i32 4357; CHECK-NEXT: [[R:%.*]] = and i32 [[ZX]], [[ZY]] 4358; CHECK-NEXT: ret i32 [[R]] 4359; 4360 %zx = zext i8 %x to i32 4361 call void @use(i32 %zx) 4362 %zy = zext i4 %y to i32 4363 %r = and i32 %zx, %zy 4364 ret i32 %r 4365} 4366 4367; negative test - don't create an extra instruction 4368 4369define i32 @or_sext_sext_use1(i8 %x, i4 %y) { 4370; CHECK-LABEL: define {{[^@]+}}@or_sext_sext_use1 4371; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) { 4372; CHECK-NEXT: [[SX:%.*]] = sext i8 [[X]] to i32 4373; CHECK-NEXT: [[SY:%.*]] = sext i4 [[Y]] to i32 4374; CHECK-NEXT: call void @use(i32 [[SY]]) 4375; CHECK-NEXT: [[R:%.*]] = or i32 [[SX]], [[SY]] 4376; CHECK-NEXT: ret i32 [[R]] 4377; 4378 %sx = sext i8 %x to i32 4379 %sy = sext i4 %y to i32 4380 call void @use(i32 %sy) 4381 %r = or i32 %sx, %sy 4382 ret i32 %r 4383} 4384 4385define i1 @PR56294(i8 %x) { 4386; CHECK-LABEL: define {{[^@]+}}@PR56294 4387; CHECK-SAME: (i8 [[X:%.*]]) { 4388; CHECK-NEXT: ret i1 false 4389; 4390 %t2 = icmp eq i8 %x, 2 4391 %t3 = and i8 %x, 1 4392 %t4 = zext i1 %t2 to i32 4393 %t5 = zext i8 %t3 to i32 4394 %t6 = and i32 %t4, %t5 4395 %t7 = icmp ne i32 %t6, 0 4396 ret i1 %t7 4397} 4398 4399define i32 @canonicalize_logic_first_or0(i32 %x) { 4400; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or0 4401; CHECK-SAME: (i32 [[X:%.*]]) { 4402; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X]], 15 4403; CHECK-NEXT: [[R:%.*]] = add i32 [[TMP1]], 112 4404; CHECK-NEXT: ret i32 [[R]] 4405; 4406 %a = add i32 %x, 112 ; 01110000 4407 %r = or i32 %a, 15 ; 00001111 4408 ret i32 %r 4409} 4410 4411define i32 @canonicalize_logic_first_or0_nsw(i32 %x) { 4412; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or0_nsw 4413; CHECK-SAME: (i32 [[X:%.*]]) { 4414; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X]], 15 4415; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 112 4416; CHECK-NEXT: ret i32 [[R]] 4417; 4418 %a = add nsw i32 %x, 112 ; 01110000 4419 %r = or i32 %a, 15 ; 00001111 4420 ret i32 %r 4421} 4422 4423define i32 @canonicalize_logic_first_or0_nswnuw(i32 %x) { 4424; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or0_nswnuw 4425; CHECK-SAME: (i32 [[X:%.*]]) { 4426; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X]], 15 4427; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[TMP1]], 112 4428; CHECK-NEXT: ret i32 [[R]] 4429; 4430 %a = add nsw nuw i32 %x, 112 ; 01110000 4431 %r = or i32 %a, 15 ; 00001111 4432 ret i32 %r 4433} 4434 4435define <2 x i32> @canonicalize_logic_first_or_vector0(<2 x i32> %x) { 4436; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector0 4437; CHECK-SAME: (<2 x i32> [[X:%.*]]) { 4438; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[X]], splat (i32 15) 4439; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[TMP1]], splat (i32 112) 4440; CHECK-NEXT: ret <2 x i32> [[R]] 4441; 4442 %a = add <2 x i32> <i32 112, i32 112>, %x ; <0x00000070, 0x00000070> 4443 %r = or <2 x i32> <i32 15, i32 15>, %a ; <0x0000000F, 0x0000000F> 4444 ret <2 x i32> %r 4445} 4446 4447define <2 x i32> @canonicalize_logic_first_or_vector0_nsw(<2 x i32> %x) { 4448; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector0_nsw 4449; CHECK-SAME: (<2 x i32> [[X:%.*]]) { 4450; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[X]], splat (i32 15) 4451; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[TMP1]], splat (i32 112) 4452; CHECK-NEXT: ret <2 x i32> [[R]] 4453; 4454 %a = add nsw <2 x i32> <i32 112, i32 112>, %x ; <0x00000070, 0x00000070> 4455 %r = or <2 x i32> <i32 15, i32 15>, %a ; <0x0000000F, 0x0000000F> 4456 ret <2 x i32> %r 4457} 4458 4459define <2 x i32> @canonicalize_logic_first_or_vector0_nswnuw(<2 x i32> %x) { 4460; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector0_nswnuw 4461; CHECK-SAME: (<2 x i32> [[X:%.*]]) { 4462; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[X]], splat (i32 15) 4463; CHECK-NEXT: [[R:%.*]] = add nuw nsw <2 x i32> [[TMP1]], splat (i32 112) 4464; CHECK-NEXT: ret <2 x i32> [[R]] 4465; 4466 %a = add nsw nuw <2 x i32> <i32 112, i32 112>, %x ; <0x00000070, 0x00000070> 4467 %r = or <2 x i32> <i32 15, i32 15>, %a ; <0x0000000F, 0x0000000F> 4468 ret <2 x i32> %r 4469} 4470 4471define <2 x i32> @canonicalize_logic_first_or_vector1(<2 x i32> %x) { 4472; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector1 4473; CHECK-SAME: (<2 x i32> [[X:%.*]]) { 4474; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[X]], <i32 -8388608, i32 2071986176> 4475; CHECK-NEXT: [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063> 4476; CHECK-NEXT: ret <2 x i32> [[R]] 4477; 4478 %a = add <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000> 4479 %r = or <2 x i32> <i32 32783, i32 2063>, %a ; <0x0000800F, 0x0000080F> 4480 ret <2 x i32> %r 4481} 4482 4483define <2 x i32> @canonicalize_logic_first_or_vector1_nsw(<2 x i32> %x) { 4484; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector1_nsw 4485; CHECK-SAME: (<2 x i32> [[X:%.*]]) { 4486; CHECK-NEXT: [[A:%.*]] = add nsw <2 x i32> [[X]], <i32 -8388608, i32 2071986176> 4487; CHECK-NEXT: [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063> 4488; CHECK-NEXT: ret <2 x i32> [[R]] 4489; 4490 %a = add nsw <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000> 4491 %r = or <2 x i32> <i32 32783, i32 2063>, %a ; <0x0000800F, 0x0000080F> 4492 ret <2 x i32> %r 4493} 4494 4495define <2 x i32> @canonicalize_logic_first_or_vector1_nswnuw(<2 x i32> %x) { 4496; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector1_nswnuw 4497; CHECK-SAME: (<2 x i32> [[X:%.*]]) { 4498; CHECK-NEXT: [[A:%.*]] = add nuw nsw <2 x i32> [[X]], <i32 -8388608, i32 2071986176> 4499; CHECK-NEXT: [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063> 4500; CHECK-NEXT: ret <2 x i32> [[R]] 4501; 4502 %a = add nsw nuw <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000> 4503 %r = or <2 x i32> <i32 32783, i32 2063>, %a ; <0x0000800F, 0x0000080F> 4504 ret <2 x i32> %r 4505} 4506 4507define <2 x i32> @canonicalize_logic_first_or_vector2(<2 x i32> %x) { 4508; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector2 4509; CHECK-SAME: (<2 x i32> [[X:%.*]]) { 4510; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[X]], <i32 2147483632, i32 2147483640> 4511; CHECK-NEXT: [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063> 4512; CHECK-NEXT: ret <2 x i32> [[R]] 4513; 4514 %a = add <2 x i32> <i32 2147483632, i32 2147483640>, %x ; <0x7FFFFFF0, 0x7FFFFFF8> 4515 %r = or <2 x i32> <i32 32783, i32 2063>, %a ; <0x0000800F, 0x0000080F> 4516 ret <2 x i32> %r 4517} 4518 4519define i32 @canonicalize_logic_first_or_mult_use1(i32 %x) { 4520; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_mult_use1 4521; CHECK-SAME: (i32 [[X:%.*]]) { 4522; CHECK-NEXT: [[A:%.*]] = add i32 [[X]], 112 4523; CHECK-NEXT: call void @use(i32 [[A]]) 4524; CHECK-NEXT: [[R:%.*]] = or i32 [[A]], 15 4525; CHECK-NEXT: ret i32 [[R]] 4526; 4527 %a = add i32 %x, 112 ; 01110000 4528 call void @use(i32 %a) 4529 %r = or i32 %a, 15 ; 00001111 4530 ret i32 %r 4531} 4532 4533define i32 @canonicalize_logic_first_or_bad_constraints2(i32 %x) { 4534; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_bad_constraints2 4535; CHECK-SAME: (i32 [[X:%.*]]) { 4536; CHECK-NEXT: [[A:%.*]] = add i32 [[X]], 112 4537; CHECK-NEXT: [[R:%.*]] = or i32 [[A]], 16 4538; CHECK-NEXT: ret i32 [[R]] 4539; 4540 %a = add i32 %x, 112 ; 01110000 4541 %r = or i32 %a, 16 ; 00010000 4542 ret i32 %r 4543} 4544 4545define i8 @canonicalize_logic_first_and0(i8 %x) { 4546; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and0 4547; CHECK-SAME: (i8 [[X:%.*]]) { 4548; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -10 4549; CHECK-NEXT: [[R:%.*]] = add i8 [[TMP1]], 48 4550; CHECK-NEXT: ret i8 [[R]] 4551; 4552 %b = add i8 %x, 48 ; 00110000 4553 %r = and i8 %b, -10 ; 11110110 4554 ret i8 %r 4555} 4556 4557define i8 @canonicalize_logic_first_and0_nsw(i8 %x) { 4558; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and0_nsw 4559; CHECK-SAME: (i8 [[X:%.*]]) { 4560; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -10 4561; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[TMP1]], 48 4562; CHECK-NEXT: ret i8 [[R]] 4563; 4564 %b = add nsw i8 %x, 48 ; 00110000 4565 %r = and i8 %b, -10 ; 11110110 4566 ret i8 %r 4567} 4568 4569define i8 @canonicalize_logic_first_and0_nswnuw(i8 %x) { 4570; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and0_nswnuw 4571; CHECK-SAME: (i8 [[X:%.*]]) { 4572; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -10 4573; CHECK-NEXT: [[R:%.*]] = add nuw nsw i8 [[TMP1]], 48 4574; CHECK-NEXT: ret i8 [[R]] 4575; 4576 %b = add nsw nuw i8 %x, 48 ; 00110000 4577 %r = and i8 %b, -10 ; 11110110 4578 ret i8 %r 4579} 4580 4581define <2 x i8> @canonicalize_logic_first_and_vector0(<2 x i8> %x) { 4582; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector0 4583; CHECK-SAME: (<2 x i8> [[X:%.*]]) { 4584; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 -10) 4585; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[TMP1]], splat (i8 48) 4586; CHECK-NEXT: ret <2 x i8> [[R]] 4587; 4588 %a = add <2 x i8> <i8 48, i8 48>, %x 4589 %r = and <2 x i8> <i8 -10, i8 -10>, %a 4590 ret <2 x i8> %r 4591} 4592 4593define <2 x i8> @canonicalize_logic_first_and_vector0_nsw(<2 x i8> %x) { 4594; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector0_nsw 4595; CHECK-SAME: (<2 x i8> [[X:%.*]]) { 4596; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 -10) 4597; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i8> [[TMP1]], splat (i8 48) 4598; CHECK-NEXT: ret <2 x i8> [[R]] 4599; 4600 %a = add nsw <2 x i8> <i8 48, i8 48>, %x 4601 %r = and <2 x i8> <i8 -10, i8 -10>, %a 4602 ret <2 x i8> %r 4603} 4604 4605define <2 x i8> @canonicalize_logic_first_and_vector0_nswnuw(<2 x i8> %x) { 4606; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector0_nswnuw 4607; CHECK-SAME: (<2 x i8> [[X:%.*]]) { 4608; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 -10) 4609; CHECK-NEXT: [[R:%.*]] = add nuw nsw <2 x i8> [[TMP1]], splat (i8 48) 4610; CHECK-NEXT: ret <2 x i8> [[R]] 4611; 4612 %a = add nsw nuw <2 x i8> <i8 48, i8 48>, %x 4613 %r = and <2 x i8> <i8 -10, i8 -10>, %a 4614 ret <2 x i8> %r 4615} 4616 4617; element-wise the constants match constraints 4618define <2 x i8> @canonicalize_logic_first_and_vector1(<2 x i8> %x) { 4619; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector1 4620; CHECK-SAME: (<2 x i8> [[X:%.*]]) { 4621; CHECK-NEXT: [[A:%.*]] = add <2 x i8> [[X]], <i8 48, i8 32> 4622; CHECK-NEXT: [[R:%.*]] = and <2 x i8> [[A]], <i8 -10, i8 -4> 4623; CHECK-NEXT: ret <2 x i8> [[R]] 4624; 4625 %a = add <2 x i8> <i8 48, i8 32>, %x 4626 %r = and <2 x i8> <i8 -10, i8 -4>, %a 4627 ret <2 x i8> %r 4628} 4629 4630; elementwise these constants do match constraints needed to canonicalize 4631; logic op first then math op 4632define <2 x i32> @canonicalize_logic_first_and_vector2(<2 x i32> %x) { 4633; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector2 4634; CHECK-SAME: (<2 x i32> [[X:%.*]]) { 4635; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[X]], splat (i32 612368384) 4636; CHECK-NEXT: [[R:%.*]] = and <2 x i32> [[A]], <i32 -65536, i32 -32768> 4637; CHECK-NEXT: ret <2 x i32> [[R]] 4638; 4639 %a = add <2 x i32> <i32 612368384, i32 612368384>, %x ; <0x24800000, 0x24800000> 4640 %r = and <2 x i32> <i32 -65536, i32 -32768>, %a ; <0xFFFF0000, 0xFFFF8000> 4641 ret <2 x i32> %r 4642} 4643 4644define <2 x i32> @canonicalize_logic_first_and_vector3(<2 x i32> %x) { 4645; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector3 4646; CHECK-SAME: (<2 x i32> [[X:%.*]]) { 4647; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[X]], <i32 32768, i32 16384> 4648; CHECK-NEXT: [[R:%.*]] = and <2 x i32> [[A]], <i32 -65536, i32 -32768> 4649; CHECK-NEXT: ret <2 x i32> [[R]] 4650; 4651 %a = add <2 x i32> <i32 32768, i32 16384>, %x ; <0x00008000, 0x00004000> 4652 %r = and <2 x i32> <i32 -65536, i32 -32768>, %a ; <0xFFFF0000, 0xFFFF8000> 4653 ret <2 x i32> %r 4654} 4655 4656define i8 @canonicalize_logic_first_and_mult_use1(i8 %x) { 4657; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_mult_use1 4658; CHECK-SAME: (i8 [[X:%.*]]) { 4659; CHECK-NEXT: [[B:%.*]] = add i8 [[X]], 48 4660; CHECK-NEXT: call void @use_i8(i8 [[B]]) 4661; CHECK-NEXT: [[R:%.*]] = and i8 [[B]], -10 4662; CHECK-NEXT: ret i8 [[R]] 4663; 4664 %b = add i8 %x, 48 ; 00110000 4665 call void @use_i8(i8 %b) 4666 %r = and i8 %b, -10 ; 11110110 4667 ret i8 %r 4668} 4669 4670define i8 @canonicalize_logic_first_and_bad_constraints2(i8 %x) { 4671; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_bad_constraints2 4672; CHECK-SAME: (i8 [[X:%.*]]) { 4673; CHECK-NEXT: [[B:%.*]] = add i8 [[X]], 48 4674; CHECK-NEXT: [[R:%.*]] = and i8 [[B]], -26 4675; CHECK-NEXT: ret i8 [[R]] 4676; 4677 %b = add i8 %x, 48 ; 00110000 4678 %r = and i8 %b, -26 ; 11100110 4679 ret i8 %r 4680} 4681 4682define i8 @canonicalize_logic_first_xor_0(i8 %x) { 4683; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_0 4684; CHECK-SAME: (i8 [[X:%.*]]) { 4685; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], 31 4686; CHECK-NEXT: [[R:%.*]] = add i8 [[TMP1]], 96 4687; CHECK-NEXT: ret i8 [[R]] 4688; 4689 %a = add i8 %x, 96 ; 01100000 4690 %r = xor i8 %a, 31 ; 00011111 4691 ret i8 %r 4692} 4693 4694define i8 @canonicalize_logic_first_xor_0_nsw(i8 %x) { 4695; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_0_nsw 4696; CHECK-SAME: (i8 [[X:%.*]]) { 4697; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], 31 4698; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[TMP1]], 96 4699; CHECK-NEXT: ret i8 [[R]] 4700; 4701 %a = add nsw i8 %x, 96 ; 01100000 4702 %r = xor i8 %a, 31 ; 00011111 4703 ret i8 %r 4704} 4705 4706define i8 @canonicalize_logic_first_xor_0_nswnuw(i8 %x) { 4707; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_0_nswnuw 4708; CHECK-SAME: (i8 [[X:%.*]]) { 4709; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], 31 4710; CHECK-NEXT: [[R:%.*]] = add nuw nsw i8 [[TMP1]], 96 4711; CHECK-NEXT: ret i8 [[R]] 4712; 4713 %a = add nsw nuw i8 %x, 96 ; 01100000 4714 %r = xor i8 %a, 31 ; 00011111 4715 ret i8 %r 4716} 4717 4718define <2 x i32> @canonicalize_logic_first_xor_vector0(<2 x i32> %x) { 4719; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector0 4720; CHECK-SAME: (<2 x i32> [[X:%.*]]) { 4721; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X]], splat (i32 32783) 4722; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[TMP1]], splat (i32 -8388608) 4723; CHECK-NEXT: ret <2 x i32> [[R]] 4724; 4725 %a = add <2 x i32> <i32 -8388608, i32 -8388608>, %x ; <0xFF800000, 0xFF800000> 4726 %r = xor <2 x i32> <i32 32783, i32 32783>, %a ; <0x0000800F, 0x0000800F> 4727 ret <2 x i32> %r 4728} 4729 4730define <2 x i32> @canonicalize_logic_first_xor_vector0_nsw(<2 x i32> %x) { 4731; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector0_nsw 4732; CHECK-SAME: (<2 x i32> [[X:%.*]]) { 4733; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X]], splat (i32 32783) 4734; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[TMP1]], splat (i32 -8388608) 4735; CHECK-NEXT: ret <2 x i32> [[R]] 4736; 4737 %a = add nsw <2 x i32> <i32 -8388608, i32 -8388608>, %x ; <0xFF800000, 0xFF800000> 4738 %r = xor <2 x i32> <i32 32783, i32 32783>, %a ; <0x0000800F, 0x0000800F> 4739 ret <2 x i32> %r 4740} 4741 4742define <2 x i32> @canonicalize_logic_first_xor_vector0_nswnuw(<2 x i32> %x) { 4743; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector0_nswnuw 4744; CHECK-SAME: (<2 x i32> [[X:%.*]]) { 4745; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X]], splat (i32 32783) 4746; CHECK-NEXT: [[R:%.*]] = add nuw nsw <2 x i32> [[TMP1]], splat (i32 -8388608) 4747; CHECK-NEXT: ret <2 x i32> [[R]] 4748; 4749 %a = add nsw nuw <2 x i32> <i32 -8388608, i32 -8388608>, %x ; <0xFF800000, 0xFF800000> 4750 %r = xor <2 x i32> <i32 32783, i32 32783>, %a ; <0x0000800F, 0x0000800F> 4751 ret <2 x i32> %r 4752} 4753 4754define <2 x i32> @canonicalize_logic_first_xor_vector1(<2 x i32> %x) { 4755; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector1 4756; CHECK-SAME: (<2 x i32> [[X:%.*]]) { 4757; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[X]], <i32 -8388608, i32 2071986176> 4758; CHECK-NEXT: [[R:%.*]] = xor <2 x i32> [[A]], <i32 32783, i32 2063> 4759; CHECK-NEXT: ret <2 x i32> [[R]] 4760; 4761 %a = add <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000> 4762 %r = xor <2 x i32> <i32 32783, i32 2063>, %a ; <0x0000800F, 0x0000080F> 4763 ret <2 x i32> %r 4764} 4765 4766define <2 x i32> @canonicalize_logic_first_xor_vector2(<2 x i32> %x) { 4767; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector2 4768; CHECK-SAME: (<2 x i32> [[X:%.*]]) { 4769; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[X]], <i32 2147483632, i32 2147483640> 4770; CHECK-NEXT: [[R:%.*]] = xor <2 x i32> [[A]], <i32 32783, i32 2063> 4771; CHECK-NEXT: ret <2 x i32> [[R]] 4772; 4773 %a = add <2 x i32> <i32 2147483632, i32 2147483640>, %x ; <0x7FFFFFF0, 0x7FFFFFF8> 4774 %r = xor <2 x i32> <i32 32783, i32 2063>, %a ; <0x0000800F, 0x0000080F> 4775 ret <2 x i32> %r 4776} 4777 4778define i8 @canonicalize_logic_first_xor_mult_use1(i8 %x) { 4779; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_mult_use1 4780; CHECK-SAME: (i8 [[X:%.*]]) { 4781; CHECK-NEXT: [[A:%.*]] = add i8 [[X]], 96 4782; CHECK-NEXT: call void @use_i8(i8 [[A]]) 4783; CHECK-NEXT: [[R:%.*]] = xor i8 [[A]], 31 4784; CHECK-NEXT: ret i8 [[R]] 4785; 4786 %a = add i8 %x, 96 ; 01100000 4787 call void @use_i8(i8 %a) 4788 %r = xor i8 %a, 31 ; 00011111 4789 ret i8 %r 4790} 4791 4792define i8 @canonicalize_logic_first_xor_bad_constants2(i8 %x) { 4793; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_bad_constants2 4794; CHECK-SAME: (i8 [[X:%.*]]) { 4795; CHECK-NEXT: [[A:%.*]] = add i8 [[X]], 96 4796; CHECK-NEXT: [[R:%.*]] = xor i8 [[A]], 32 4797; CHECK-NEXT: ret i8 [[R]] 4798; 4799 %a = add i8 %x, 96 ; 01100000 4800 %r = xor i8 %a, 32 ; 00100000 4801 ret i8 %r 4802} 4803 4804@g = external global i8 4805 4806define i32 @canonicalize_logic_first_constexpr(i32 %x) { 4807; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_constexpr 4808; CHECK-SAME: (i32 [[X:%.*]]) { 4809; CHECK-NEXT: [[R:%.*]] = and i32 add (i32 ptrtoint (ptr @g to i32), i32 48), -10 4810; CHECK-NEXT: ret i32 [[R]] 4811; 4812 %a = add i32 ptrtoint (ptr @g to i32), 48 4813 %r = and i32 %a, -10 4814 ret i32 %r 4815} 4816 4817define i32 @canonicalize_logic_first_constexpr_nuw(i32 %x) { 4818; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_constexpr_nuw 4819; CHECK-SAME: (i32 [[X:%.*]]) { 4820; CHECK-NEXT: [[R:%.*]] = and i32 add (i32 ptrtoint (ptr @g to i32), i32 48), -10 4821; CHECK-NEXT: ret i32 [[R]] 4822; 4823 %a = add nuw i32 ptrtoint (ptr @g to i32), 48 4824 %r = and i32 %a, -10 4825 ret i32 %r 4826} 4827 4828define i1 @test_and_xor_freely_invertable(i32 %x, i32 %y, i1 %z) { 4829; CHECK-LABEL: define {{[^@]+}}@test_and_xor_freely_invertable 4830; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i1 [[Z:%.*]]) { 4831; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X]], [[Y]] 4832; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[Z]] 4833; CHECK-NEXT: ret i1 [[AND]] 4834; 4835 %cmp = icmp sgt i32 %x, %y 4836 %xor = xor i1 %cmp, %z 4837 %and = and i1 %xor, %z 4838 ret i1 %and 4839} 4840 4841define i1 @test_and_xor_freely_invertable_multiuse(i32 %x, i32 %y, i1 %z) { 4842; CHECK-LABEL: define {{[^@]+}}@test_and_xor_freely_invertable_multiuse 4843; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i1 [[Z:%.*]]) { 4844; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], [[Y]] 4845; CHECK-NEXT: call void @use_i1(i1 [[CMP]]) 4846; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[CMP]], true 4847; CHECK-NEXT: [[AND:%.*]] = and i1 [[Z]], [[TMP1]] 4848; CHECK-NEXT: ret i1 [[AND]] 4849; 4850 %cmp = icmp sgt i32 %x, %y 4851 call void @use_i1(i1 %cmp) 4852 %xor = xor i1 %cmp, %z 4853 %and = and i1 %xor, %z 4854 ret i1 %and 4855} 4856