1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4; PR1253 5define i1 @test0(i32 %A) { 6; CHECK-LABEL: @test0( 7; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[A:%.*]], 0 8; CHECK-NEXT: ret i1 [[C]] 9; 10 %B = xor i32 %A, -2147483648 11 %C = icmp sgt i32 %B, -1 12 ret i1 %C 13} 14 15define <2 x i1> @test0vec(<2 x i32> %A) { 16; CHECK-LABEL: @test0vec( 17; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> [[A:%.*]], zeroinitializer 18; CHECK-NEXT: ret <2 x i1> [[C]] 19; 20 %B = xor <2 x i32> %A, <i32 -2147483648, i32 -2147483648> 21 %C = icmp sgt <2 x i32> %B, <i32 -1, i32 -1> 22 ret <2 x i1> %C 23} 24 25define i1 @test1(i32 %A) { 26; CHECK-LABEL: @test1( 27; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[A:%.*]], 0 28; CHECK-NEXT: ret i1 [[C]] 29; 30 %B = xor i32 %A, 12345 31 %C = icmp slt i32 %B, 0 32 ret i1 %C 33} 34 35; PR1014 36define i32 @test2(i32 %tmp1) { 37; CHECK-LABEL: @test2( 38; CHECK-NEXT: [[OVM:%.*]] = and i32 [[TMP1:%.*]], 32 39; CHECK-NEXT: [[OV1101:%.*]] = or i32 [[OVM]], 8 40; CHECK-NEXT: ret i32 [[OV1101]] 41; 42 %ovm = and i32 %tmp1, 32 43 %ov3 = add i32 %ovm, 145 44 %ov110 = xor i32 %ov3, 153 45 ret i32 %ov110 46} 47 48define i32 @test3(i32 %tmp1) { 49; CHECK-LABEL: @test3( 50; CHECK-NEXT: [[OVM:%.*]] = and i32 [[TMP1:%.*]], 32 51; CHECK-NEXT: [[OV1101:%.*]] = or i32 [[OVM]], 8 52; CHECK-NEXT: ret i32 [[OV1101]] 53; 54 %ovm = or i32 %tmp1, 145 55 %ov31 = and i32 %ovm, 177 56 %ov110 = xor i32 %ov31, 153 57 ret i32 %ov110 58} 59 60; defect-2 in rdar://12329730 61; (X^C1) >> C2) ^ C3 -> (X>>C2) ^ ((C1>>C2)^C3) 62; where the "X" has more than one use 63define i32 @test5(i32 %val1) { 64; CHECK-LABEL: @test5( 65; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[VAL1:%.*]], 1234 66; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[VAL1]], 8 67; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[SHR]], 5 68; CHECK-NEXT: [[ADD:%.*]] = add i32 [[XOR1]], [[XOR]] 69; CHECK-NEXT: ret i32 [[ADD]] 70; 71 %xor = xor i32 %val1, 1234 72 %shr = lshr i32 %xor, 8 73 %xor1 = xor i32 %shr, 1 74 %add = add i32 %xor1, %xor 75 ret i32 %add 76} 77 78; defect-1 in rdar://12329730 79; Simplify (X^Y) -> X or Y in the user's context if we know that 80; only bits from X or Y are demanded. 81; e.g. the "x ^ 1234" can be optimized into x in the context of "t >> 16". 82; Put in other word, t >> 16 -> x >> 16. 83; unsigned foo(unsigned x) { unsigned t = x ^ 1234; ; return (t >> 16) + t;} 84define i32 @test6(i32 %x) { 85; CHECK-LABEL: @test6( 86; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], 1234 87; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 16 88; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SHR]], [[XOR]] 89; CHECK-NEXT: ret i32 [[ADD]] 90; 91 %xor = xor i32 %x, 1234 92 %shr = lshr i32 %xor, 16 93 %add = add i32 %shr, %xor 94 ret i32 %add 95} 96 97 98; (A | B) ^ (~A) -> (A | ~B) 99define i32 @test7(i32 %a, i32 %b) { 100; CHECK-LABEL: @test7( 101; CHECK-NEXT: [[B_NOT:%.*]] = xor i32 [[B:%.*]], -1 102; CHECK-NEXT: [[XOR:%.*]] = or i32 [[B_NOT]], [[A:%.*]] 103; CHECK-NEXT: ret i32 [[XOR]] 104; 105 %or = or i32 %a, %b 106 %neg = xor i32 %a, -1 107 %xor = xor i32 %or, %neg 108 ret i32 %xor 109} 110 111; (~A) ^ (A | B) -> (A | ~B) 112define i32 @test8(i32 %a, i32 %b) { 113; CHECK-LABEL: @test8( 114; CHECK-NEXT: [[B_NOT:%.*]] = xor i32 [[B:%.*]], -1 115; CHECK-NEXT: [[XOR:%.*]] = or i32 [[B_NOT]], [[A:%.*]] 116; CHECK-NEXT: ret i32 [[XOR]] 117; 118 %neg = xor i32 %a, -1 119 %or = or i32 %a, %b 120 %xor = xor i32 %neg, %or 121 ret i32 %xor 122} 123 124; (A & B) ^ (A ^ B) -> (A | B) 125define i32 @test9(i32 %b, i32 %c) { 126; CHECK-LABEL: @test9( 127; CHECK-NEXT: [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]] 128; CHECK-NEXT: ret i32 [[XOR2]] 129; 130 %and = and i32 %b, %c 131 %xor = xor i32 %b, %c 132 %xor2 = xor i32 %and, %xor 133 ret i32 %xor2 134} 135 136; (A & B) ^ (B ^ A) -> (A | B) 137define i32 @test9b(i32 %b, i32 %c) { 138; CHECK-LABEL: @test9b( 139; CHECK-NEXT: [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]] 140; CHECK-NEXT: ret i32 [[XOR2]] 141; 142 %and = and i32 %b, %c 143 %xor = xor i32 %c, %b 144 %xor2 = xor i32 %and, %xor 145 ret i32 %xor2 146} 147 148; (A ^ B) ^ (A & B) -> (A | B) 149define i32 @test10(i32 %b, i32 %c) { 150; CHECK-LABEL: @test10( 151; CHECK-NEXT: [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]] 152; CHECK-NEXT: ret i32 [[XOR2]] 153; 154 %xor = xor i32 %b, %c 155 %and = and i32 %b, %c 156 %xor2 = xor i32 %xor, %and 157 ret i32 %xor2 158} 159 160; (A ^ B) ^ (A & B) -> (A | B) 161define i32 @test10b(i32 %b, i32 %c) { 162; CHECK-LABEL: @test10b( 163; CHECK-NEXT: [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]] 164; CHECK-NEXT: ret i32 [[XOR2]] 165; 166 %xor = xor i32 %b, %c 167 %and = and i32 %c, %b 168 %xor2 = xor i32 %xor, %and 169 ret i32 %xor2 170} 171 172define i32 @test11(i32 %A, i32 %B) { 173; CHECK-LABEL: @test11( 174; CHECK-NEXT: ret i32 0 175; 176 %xor1 = xor i32 %B, %A 177 %not = xor i32 %A, -1 178 %xor2 = xor i32 %not, %B 179 %and = and i32 %xor1, %xor2 180 ret i32 %and 181} 182 183define i32 @test11b(i32 %A, i32 %B) { 184; CHECK-LABEL: @test11b( 185; CHECK-NEXT: ret i32 0 186; 187 %xor1 = xor i32 %B, %A 188 %not = xor i32 %A, -1 189 %xor2 = xor i32 %not, %B 190 %and = and i32 %xor2, %xor1 191 ret i32 %and 192} 193 194define i32 @test11c(i32 %A, i32 %B) { 195; CHECK-LABEL: @test11c( 196; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 197; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A]], -1 198; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[NOT]], [[B]] 199; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]] 200; CHECK-NEXT: ret i32 [[AND]] 201; 202 %xor1 = xor i32 %A, %B 203 %not = xor i32 %A, -1 204 %xor2 = xor i32 %not, %B 205 %and = and i32 %xor1, %xor2 206 ret i32 %and 207} 208 209define i32 @test11d(i32 %A, i32 %B) { 210; CHECK-LABEL: @test11d( 211; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] 212; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A]], -1 213; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[NOT]], [[B]] 214; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR2]], [[XOR1]] 215; CHECK-NEXT: ret i32 [[AND]] 216; 217 %xor1 = xor i32 %A, %B 218 %not = xor i32 %A, -1 219 %xor2 = xor i32 %not, %B 220 %and = and i32 %xor2, %xor1 221 ret i32 %and 222} 223 224define i32 @test11e(i32 %A, i32 %B, i32 %C) { 225; CHECK-LABEL: @test11e( 226; CHECK-NEXT: [[FORCE:%.*]] = mul i32 [[B:%.*]], [[C:%.*]] 227; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[FORCE]], [[A:%.*]] 228; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A]], -1 229; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[FORCE]], [[NOT]] 230; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]] 231; CHECK-NEXT: ret i32 [[AND]] 232; 233 %force = mul i32 %B, %C 234 %xor1 = xor i32 %force, %A 235 %not = xor i32 %A, -1 236 %xor2 = xor i32 %force, %not 237 %and = and i32 %xor1, %xor2 238 ret i32 %and 239} 240 241define i32 @test11f(i32 %A, i32 %B, i32 %C) { 242; CHECK-LABEL: @test11f( 243; CHECK-NEXT: [[FORCE:%.*]] = mul i32 [[B:%.*]], [[C:%.*]] 244; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[FORCE]], [[A:%.*]] 245; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A]], -1 246; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[FORCE]], [[NOT]] 247; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR2]], [[XOR1]] 248; CHECK-NEXT: ret i32 [[AND]] 249; 250 %force = mul i32 %B, %C 251 %xor1 = xor i32 %force, %A 252 %not = xor i32 %A, -1 253 %xor2 = xor i32 %force, %not 254 %and = and i32 %xor2, %xor1 255 ret i32 %and 256} 257 258define i32 @test12(i32 %a, i32 %b) { 259; CHECK-LABEL: @test12( 260; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 261; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 262; CHECK-NEXT: ret i32 [[XOR]] 263; 264 %negb = xor i32 %b, -1 265 %and = and i32 %a, %negb 266 %nega = xor i32 %a, -1 267 %xor = xor i32 %and, %nega 268 ret i32 %xor 269} 270 271define i32 @test12commuted(i32 %a, i32 %b) { 272; CHECK-LABEL: @test12commuted( 273; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 274; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 275; CHECK-NEXT: ret i32 [[XOR]] 276; 277 %negb = xor i32 %b, -1 278 %and = and i32 %negb, %a 279 %nega = xor i32 %a, -1 280 %xor = xor i32 %and, %nega 281 ret i32 %xor 282} 283 284; This is a test of canonicalization via operand complexity. 285; The final xor has a binary operator and a (fake) unary operator, 286; so binary (more complex) should come first. 287 288define i32 @test13(i32 %a, i32 %b) { 289; CHECK-LABEL: @test13( 290; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 291; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 292; CHECK-NEXT: ret i32 [[XOR]] 293; 294 %nega = xor i32 %a, -1 295 %negb = xor i32 %b, -1 296 %and = and i32 %a, %negb 297 %xor = xor i32 %nega, %and 298 ret i32 %xor 299} 300 301define i32 @test13commuted(i32 %a, i32 %b) { 302; CHECK-LABEL: @test13commuted( 303; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 304; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 305; CHECK-NEXT: ret i32 [[XOR]] 306; 307 %nega = xor i32 %a, -1 308 %negb = xor i32 %b, -1 309 %and = and i32 %negb, %a 310 %xor = xor i32 %nega, %and 311 ret i32 %xor 312} 313 314; (A ^ C) ^ (A | B) -> ((~A) & B) ^ C 315 316define i32 @xor_or_xor_common_op_commute1(i32 %a, i32 %b, i32 %c) { 317; CHECK-LABEL: @xor_or_xor_common_op_commute1( 318; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 319; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[B:%.*]] 320; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 321; CHECK-NEXT: ret i32 [[R]] 322; 323 %ac = xor i32 %a, %c 324 %ab = or i32 %a, %b 325 %r = xor i32 %ac, %ab 326 ret i32 %r 327} 328 329; (C ^ A) ^ (A | B) -> ((~A) & B) ^ C 330 331define i32 @xor_or_xor_common_op_commute2(i32 %a, i32 %b, i32 %c) { 332; CHECK-LABEL: @xor_or_xor_common_op_commute2( 333; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 334; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[B:%.*]] 335; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 336; CHECK-NEXT: ret i32 [[R]] 337; 338 %ac = xor i32 %c, %a 339 %ab = or i32 %a, %b 340 %r = xor i32 %ac, %ab 341 ret i32 %r 342} 343 344; (A ^ C) ^ (B | A) -> ((~A) & B) ^ C 345 346define i32 @xor_or_xor_common_op_commute3(i32 %a, i32 %b, i32 %c) { 347; CHECK-LABEL: @xor_or_xor_common_op_commute3( 348; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 349; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[B:%.*]] 350; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 351; CHECK-NEXT: ret i32 [[R]] 352; 353 %ac = xor i32 %a, %c 354 %ab = or i32 %b, %a 355 %r = xor i32 %ac, %ab 356 ret i32 %r 357} 358 359; (C ^ A) ^ (B | A) -> ((~A) & B) ^ C 360 361define i32 @xor_or_xor_common_op_commute4(i32 %a, i32 %b, i32 %c) { 362; CHECK-LABEL: @xor_or_xor_common_op_commute4( 363; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 364; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[B:%.*]] 365; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 366; CHECK-NEXT: ret i32 [[R]] 367; 368 %ac = xor i32 %c, %a 369 %ab = or i32 %b, %a 370 %r = xor i32 %ac, %ab 371 ret i32 %r 372} 373 374; (A | B) ^ (A ^ C) -> ((~A) & B) ^ C 375 376define i32 @xor_or_xor_common_op_commute5(i32 %a, i32 %b, i32 %c) { 377; CHECK-LABEL: @xor_or_xor_common_op_commute5( 378; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 379; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[B:%.*]] 380; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 381; CHECK-NEXT: ret i32 [[R]] 382; 383 %ac = xor i32 %a, %c 384 %ab = or i32 %a, %b 385 %r = xor i32 %ab, %ac 386 ret i32 %r 387} 388 389; (A | B) ^ (C ^ A) -> ((~A) & B) ^ C 390 391define i32 @xor_or_xor_common_op_commute6(i32 %a, i32 %b, i32 %c) { 392; CHECK-LABEL: @xor_or_xor_common_op_commute6( 393; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 394; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[B:%.*]] 395; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 396; CHECK-NEXT: ret i32 [[R]] 397; 398 %ac = xor i32 %c, %a 399 %ab = or i32 %a, %b 400 %r = xor i32 %ab, %ac 401 ret i32 %r 402} 403 404; (B | A) ^ (A ^ C) -> ((~A) & B) ^ C 405 406define i32 @xor_or_xor_common_op_commute7(i32 %a, i32 %b, i32 %c) { 407; CHECK-LABEL: @xor_or_xor_common_op_commute7( 408; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 409; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[B:%.*]] 410; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 411; CHECK-NEXT: ret i32 [[R]] 412; 413 %ac = xor i32 %a, %c 414 %ab = or i32 %b, %a 415 %r = xor i32 %ab, %ac 416 ret i32 %r 417} 418 419; (B | A) ^ (C ^ A) -> ((~A) & B) ^ C 420 421define i32 @xor_or_xor_common_op_commute8(i32 %a, i32 %b, i32 %c) { 422; CHECK-LABEL: @xor_or_xor_common_op_commute8( 423; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1 424; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[B:%.*]] 425; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]] 426; CHECK-NEXT: ret i32 [[R]] 427; 428 %ac = xor i32 %c, %a 429 %ab = or i32 %b, %a 430 %r = xor i32 %ab, %ac 431 ret i32 %r 432} 433 434define i32 @xor_or_xor_common_op_extra_use1(i32 %a, i32 %b, i32 %c, i32* %p) { 435; CHECK-LABEL: @xor_or_xor_common_op_extra_use1( 436; CHECK-NEXT: [[AC:%.*]] = xor i32 [[A:%.*]], [[C:%.*]] 437; CHECK-NEXT: store i32 [[AC]], i32* [[P:%.*]], align 4 438; CHECK-NEXT: [[AB:%.*]] = or i32 [[A]], [[B:%.*]] 439; CHECK-NEXT: [[R:%.*]] = xor i32 [[AC]], [[AB]] 440; CHECK-NEXT: ret i32 [[R]] 441; 442 %ac = xor i32 %a, %c 443 store i32 %ac, i32* %p 444 %ab = or i32 %a, %b 445 %r = xor i32 %ac, %ab 446 ret i32 %r 447} 448 449define i32 @xor_or_xor_common_op_extra_use2(i32 %a, i32 %b, i32 %c, i32* %p) { 450; CHECK-LABEL: @xor_or_xor_common_op_extra_use2( 451; CHECK-NEXT: [[AC:%.*]] = xor i32 [[A:%.*]], [[C:%.*]] 452; CHECK-NEXT: [[AB:%.*]] = or i32 [[A]], [[B:%.*]] 453; CHECK-NEXT: store i32 [[AB]], i32* [[P:%.*]], align 4 454; CHECK-NEXT: [[R:%.*]] = xor i32 [[AC]], [[AB]] 455; CHECK-NEXT: ret i32 [[R]] 456; 457 %ac = xor i32 %a, %c 458 %ab = or i32 %a, %b 459 store i32 %ab, i32* %p 460 %r = xor i32 %ac, %ab 461 ret i32 %r 462} 463 464define i32 @xor_or_xor_common_op_extra_use3(i32 %a, i32 %b, i32 %c, i32* %p1, i32* %p2) { 465; CHECK-LABEL: @xor_or_xor_common_op_extra_use3( 466; CHECK-NEXT: [[AC:%.*]] = xor i32 [[A:%.*]], [[C:%.*]] 467; CHECK-NEXT: store i32 [[AC]], i32* [[P1:%.*]], align 4 468; CHECK-NEXT: [[AB:%.*]] = or i32 [[A]], [[B:%.*]] 469; CHECK-NEXT: store i32 [[AB]], i32* [[P2:%.*]], align 4 470; CHECK-NEXT: [[R:%.*]] = xor i32 [[AC]], [[AB]] 471; CHECK-NEXT: ret i32 [[R]] 472; 473 %ac = xor i32 %a, %c 474 store i32 %ac, i32* %p1 475 %ab = or i32 %a, %b 476 store i32 %ab, i32* %p2 477 %r = xor i32 %ac, %ab 478 ret i32 %r 479} 480 481define i8 @test15(i8 %A, i8 %B) { 482; CHECK-LABEL: @test15( 483; CHECK-NEXT: [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]] 484; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[A]], 33 485; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[NOT]], [[B]] 486; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR1]], -34 487; CHECK-NEXT: [[RES:%.*]] = mul i8 [[AND]], [[XOR2]] 488; CHECK-NEXT: ret i8 [[RES]] 489; 490 %xor1 = xor i8 %B, %A 491 %not = xor i8 %A, 33 492 %xor2 = xor i8 %not, %B 493 %and = and i8 %xor1, %xor2 494 %res = mul i8 %and, %xor2 ; to increase the use count for the xor 495 ret i8 %res 496} 497 498define i8 @test16(i8 %A, i8 %B) { 499; CHECK-LABEL: @test16( 500; CHECK-NEXT: [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]] 501; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[A]], 33 502; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[NOT]], [[B]] 503; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR1]], -34 504; CHECK-NEXT: [[RES:%.*]] = mul i8 [[AND]], [[XOR2]] 505; CHECK-NEXT: ret i8 [[RES]] 506; 507 %xor1 = xor i8 %B, %A 508 %not = xor i8 %A, 33 509 %xor2 = xor i8 %not, %B 510 %and = and i8 %xor2, %xor1 511 %res = mul i8 %and, %xor2 ; to increase the use count for the xor 512 ret i8 %res 513} 514