1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -instcombine < %s | FileCheck %s 3 4; X | ~(X | Y) --> X | ~Y 5 6define i32 @test1(i32 %x, i32 %y) { 7; CHECK-LABEL: @test1( 8; CHECK-NEXT: [[Y_NOT:%.*]] = xor i32 [[Y:%.*]], -1 9; CHECK-NEXT: [[Z:%.*]] = or i32 [[Y_NOT]], [[X:%.*]] 10; CHECK-NEXT: ret i32 [[Z]] 11; 12 %or = or i32 %x, %y 13 %not = xor i32 %or, -1 14 %z = or i32 %x, %not 15 ret i32 %z 16} 17 18; Commute (rename) the inner 'or' operands: 19; Y | ~(X | Y) --> ~X | Y 20 21define i32 @test2(i32 %x, i32 %y) { 22; CHECK-LABEL: @test2( 23; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1 24; CHECK-NEXT: [[Z:%.*]] = or i32 [[X_NOT]], [[Y:%.*]] 25; CHECK-NEXT: ret i32 [[Z]] 26; 27 %or = or i32 %x, %y 28 %not = xor i32 %or, -1 29 %z = or i32 %y, %not 30 ret i32 %z 31} 32 33; X | ~(X ^ Y) --> X | ~Y 34 35define i32 @test3(i32 %x, i32 %y) { 36; CHECK-LABEL: @test3( 37; CHECK-NEXT: [[Y_NOT:%.*]] = xor i32 [[Y:%.*]], -1 38; CHECK-NEXT: [[Z:%.*]] = or i32 [[Y_NOT]], [[X:%.*]] 39; CHECK-NEXT: ret i32 [[Z]] 40; 41 %xor = xor i32 %x, %y 42 %not = xor i32 %xor, -1 43 %z = or i32 %x, %not 44 ret i32 %z 45} 46 47; Commute (rename) the 'xor' operands: 48; Y | ~(X ^ Y) --> ~X | Y 49 50define i32 @test4(i32 %x, i32 %y) { 51; CHECK-LABEL: @test4( 52; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1 53; CHECK-NEXT: [[Z:%.*]] = or i32 [[X_NOT]], [[Y:%.*]] 54; CHECK-NEXT: ret i32 [[Z]] 55; 56 %xor = xor i32 %x, %y 57 %not = xor i32 %xor, -1 58 %z = or i32 %y, %not 59 ret i32 %z 60} 61 62define i32 @test7(i32 %x, i32 %y) { 63; CHECK-LABEL: @test7( 64; CHECK-NEXT: [[Z:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] 65; CHECK-NEXT: ret i32 [[Z]] 66; 67 %xor = xor i32 %x, %y 68 %z = or i32 %y, %xor 69 ret i32 %z 70} 71 72define i32 @test8(i32 %x, i32 %y) { 73; CHECK-LABEL: @test8( 74; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1 75; CHECK-NEXT: [[Z:%.*]] = or i32 [[X_NOT]], [[Y:%.*]] 76; CHECK-NEXT: ret i32 [[Z]] 77; 78 %not = xor i32 %y, -1 79 %xor = xor i32 %x, %not 80 %z = or i32 %y, %xor 81 ret i32 %z 82} 83 84define i32 @test9(i32 %x, i32 %y) { 85; CHECK-LABEL: @test9( 86; CHECK-NEXT: [[Y_NOT:%.*]] = xor i32 [[Y:%.*]], -1 87; CHECK-NEXT: [[Z:%.*]] = or i32 [[Y_NOT]], [[X:%.*]] 88; CHECK-NEXT: ret i32 [[Z]] 89; 90 %not = xor i32 %x, -1 91 %xor = xor i32 %not, %y 92 %z = or i32 %x, %xor 93 ret i32 %z 94} 95 96define i32 @test10(i32 %A, i32 %B) { 97; CHECK-LABEL: @test10( 98; CHECK-NEXT: ret i32 -1 99; 100 %xor1 = xor i32 %B, %A 101 %not = xor i32 %A, -1 102 %xor2 = xor i32 %not, %B 103 %or = or i32 %xor1, %xor2 104 ret i32 %or 105} 106 107define i32 @test10_commuted(i32 %A, i32 %B) { 108; CHECK-LABEL: @test10_commuted( 109; CHECK-NEXT: ret i32 -1 110; 111 %xor1 = xor i32 %B, %A 112 %not = xor i32 %A, -1 113 %xor2 = xor i32 %not, %B 114 %or = or i32 %xor2, %xor1 115 ret i32 %or 116} 117 118; (x | y) & ((~x) ^ y) -> (x & y) 119define i32 @test11(i32 %x, i32 %y) { 120; CHECK-LABEL: @test11( 121; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 122; CHECK-NEXT: ret i32 [[AND]] 123; 124 %or = or i32 %x, %y 125 %neg = xor i32 %x, -1 126 %xor = xor i32 %neg, %y 127 %and = and i32 %or, %xor 128 ret i32 %and 129} 130 131; ((~x) ^ y) & (x | y) -> (x & y) 132define i32 @test12(i32 %x, i32 %y) { 133; CHECK-LABEL: @test12( 134; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 135; CHECK-NEXT: ret i32 [[AND]] 136; 137 %neg = xor i32 %x, -1 138 %xor = xor i32 %neg, %y 139 %or = or i32 %x, %y 140 %and = and i32 %xor, %or 141 ret i32 %and 142} 143 144define i32 @test12_commuted(i32 %x, i32 %y) { 145; CHECK-LABEL: @test12_commuted( 146; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] 147; CHECK-NEXT: ret i32 [[AND]] 148; 149 %neg = xor i32 %x, -1 150 %xor = xor i32 %neg, %y 151 %or = or i32 %y, %x 152 %and = and i32 %xor, %or 153 ret i32 %and 154} 155 156; ((x | y) ^ (x ^ y)) -> (x & y) 157define i32 @test13(i32 %x, i32 %y) { 158; CHECK-LABEL: @test13( 159; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 160; CHECK-NEXT: ret i32 [[TMP1]] 161; 162 %1 = xor i32 %y, %x 163 %2 = or i32 %y, %x 164 %3 = xor i32 %2, %1 165 ret i32 %3 166} 167 168; ((x | ~y) ^ (~x | y)) -> x ^ y 169define i32 @test14(i32 %x, i32 %y) { 170; CHECK-LABEL: @test14( 171; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 172; CHECK-NEXT: ret i32 [[XOR]] 173; 174 %noty = xor i32 %y, -1 175 %notx = xor i32 %x, -1 176 %or1 = or i32 %x, %noty 177 %or2 = or i32 %notx, %y 178 %xor = xor i32 %or1, %or2 179 ret i32 %xor 180} 181 182define i32 @test14_commuted(i32 %x, i32 %y) { 183; CHECK-LABEL: @test14_commuted( 184; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 185; CHECK-NEXT: ret i32 [[XOR]] 186; 187 %noty = xor i32 %y, -1 188 %notx = xor i32 %x, -1 189 %or1 = or i32 %noty, %x 190 %or2 = or i32 %notx, %y 191 %xor = xor i32 %or1, %or2 192 ret i32 %xor 193} 194 195; ((x & ~y) ^ (~x & y)) -> x ^ y 196define i32 @test15(i32 %x, i32 %y) { 197; CHECK-LABEL: @test15( 198; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 199; CHECK-NEXT: ret i32 [[XOR]] 200; 201 %noty = xor i32 %y, -1 202 %notx = xor i32 %x, -1 203 %and1 = and i32 %x, %noty 204 %and2 = and i32 %notx, %y 205 %xor = xor i32 %and1, %and2 206 ret i32 %xor 207} 208 209define i32 @test15_commuted(i32 %x, i32 %y) { 210; CHECK-LABEL: @test15_commuted( 211; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 212; CHECK-NEXT: ret i32 [[XOR]] 213; 214 %noty = xor i32 %y, -1 215 %notx = xor i32 %x, -1 216 %and1 = and i32 %noty, %x 217 %and2 = and i32 %notx, %y 218 %xor = xor i32 %and1, %and2 219 ret i32 %xor 220} 221 222define i32 @test16(i32 %a, i32 %b) { 223; CHECK-LABEL: @test16( 224; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 1 225; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], [[B:%.*]] 226; CHECK-NEXT: ret i32 [[XOR]] 227; 228 %or = xor i32 %a, %b 229 %and1 = and i32 %or, 1 230 %and2 = and i32 %b, -2 231 %xor = or i32 %and1, %and2 232 ret i32 %xor 233} 234 235define i8 @not_or(i8 %x) { 236; CHECK-LABEL: @not_or( 237; CHECK-NEXT: [[NOTX:%.*]] = xor i8 [[X:%.*]], -1 238; CHECK-NEXT: [[OR:%.*]] = or i8 [[NOTX]], 7 239; CHECK-NEXT: ret i8 [[OR]] 240; 241 %notx = xor i8 %x, -1 242 %or = or i8 %notx, 7 243 ret i8 %or 244} 245 246define i8 @not_or_xor(i8 %x) { 247; CHECK-LABEL: @not_or_xor( 248; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -8 249; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[TMP1]], -13 250; CHECK-NEXT: ret i8 [[XOR]] 251; 252 %notx = xor i8 %x, -1 253 %or = or i8 %notx, 7 254 %xor = xor i8 %or, 12 255 ret i8 %xor 256} 257 258define i8 @xor_or(i8 %x) { 259; CHECK-LABEL: @xor_or( 260; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X:%.*]], 7 261; CHECK-NEXT: [[OR:%.*]] = xor i8 [[TMP1]], 32 262; CHECK-NEXT: ret i8 [[OR]] 263; 264 %xor = xor i8 %x, 32 265 %or = or i8 %xor, 7 266 ret i8 %or 267} 268 269define i8 @xor_or2(i8 %x) { 270; CHECK-LABEL: @xor_or2( 271; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X:%.*]], 7 272; CHECK-NEXT: [[OR:%.*]] = xor i8 [[TMP1]], 32 273; CHECK-NEXT: ret i8 [[OR]] 274; 275 %xor = xor i8 %x, 33 276 %or = or i8 %xor, 7 277 ret i8 %or 278} 279 280define i8 @xor_or_xor(i8 %x) { 281; CHECK-LABEL: @xor_or_xor( 282; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X:%.*]], 7 283; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[TMP1]], 44 284; CHECK-NEXT: ret i8 [[XOR2]] 285; 286 %xor1 = xor i8 %x, 33 287 %or = or i8 %xor1, 7 288 %xor2 = xor i8 %or, 12 289 ret i8 %xor2 290} 291 292define i8 @or_xor_or(i8 %x) { 293; CHECK-LABEL: @or_xor_or( 294; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X:%.*]], 39 295; CHECK-NEXT: [[OR2:%.*]] = xor i8 [[TMP1]], 8 296; CHECK-NEXT: ret i8 [[OR2]] 297; 298 %or1 = or i8 %x, 33 299 %xor = xor i8 %or1, 12 300 %or2 = or i8 %xor, 7 301 ret i8 %or2 302} 303 304define i8 @test17(i8 %A, i8 %B) { 305; CHECK-LABEL: @test17( 306; CHECK-NEXT: [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]] 307; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[A]], 33 308; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[NOT]], [[B]] 309; CHECK-NEXT: [[OR:%.*]] = or i8 [[XOR1]], 33 310; CHECK-NEXT: [[RES:%.*]] = mul i8 [[OR]], [[XOR2]] 311; CHECK-NEXT: ret i8 [[RES]] 312; 313 %xor1 = xor i8 %B, %A 314 %not = xor i8 %A, 33 315 %xor2 = xor i8 %not, %B 316 %or = or i8 %xor1, %xor2 317 %res = mul i8 %or, %xor2 ; to increase the use count for the xor 318 ret i8 %res 319} 320 321define i8 @test18(i8 %A, i8 %B) { 322; CHECK-LABEL: @test18( 323; CHECK-NEXT: [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]] 324; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[A]], 33 325; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[NOT]], [[B]] 326; CHECK-NEXT: [[OR:%.*]] = or i8 [[XOR1]], 33 327; CHECK-NEXT: [[RES:%.*]] = mul i8 [[OR]], [[XOR2]] 328; CHECK-NEXT: ret i8 [[RES]] 329; 330 %xor1 = xor i8 %B, %A 331 %not = xor i8 %A, 33 332 %xor2 = xor i8 %not, %B 333 %or = or i8 %xor2, %xor1 334 %res = mul i8 %or, %xor2 ; to increase the use count for the xor 335 ret i8 %res 336} 337 338; ((x | y) ^ (~x | ~y)) -> ~(x ^ y) 339define i32 @test19(i32 %x, i32 %y) { 340; CHECK-LABEL: @test19( 341; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 342; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 343; CHECK-NEXT: ret i32 [[XOR]] 344; 345 %noty = xor i32 %y, -1 346 %notx = xor i32 %x, -1 347 %or1 = or i32 %x, %y 348 %or2 = or i32 %notx, %noty 349 %xor = xor i32 %or1, %or2 350 ret i32 %xor 351} 352 353; ((x | y) ^ (~y | ~x)) -> ~(x ^ y) 354define i32 @test20(i32 %x, i32 %y) { 355; CHECK-LABEL: @test20( 356; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 357; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 358; CHECK-NEXT: ret i32 [[XOR]] 359; 360 %noty = xor i32 %y, -1 361 %notx = xor i32 %x, -1 362 %or1 = or i32 %x, %y 363 %or2 = or i32 %noty, %notx 364 %xor = xor i32 %or1, %or2 365 ret i32 %xor 366} 367 368; ((~x | ~y) ^ (x | y)) -> ~(x ^ y) 369define i32 @test21(i32 %x, i32 %y) { 370; CHECK-LABEL: @test21( 371; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] 372; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 373; CHECK-NEXT: ret i32 [[XOR]] 374; 375 %noty = xor i32 %y, -1 376 %notx = xor i32 %x, -1 377 %or1 = or i32 %notx, %noty 378 %or2 = or i32 %x, %y 379 %xor = xor i32 %or1, %or2 380 ret i32 %xor 381} 382 383; ((~x | ~y) ^ (y | x)) -> ~(x ^ y) 384define i32 @test22(i32 %x, i32 %y) { 385; CHECK-LABEL: @test22( 386; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]] 387; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1 388; CHECK-NEXT: ret i32 [[XOR]] 389; 390 %noty = xor i32 %y, -1 391 %notx = xor i32 %x, -1 392 %or1 = or i32 %notx, %noty 393 %or2 = or i32 %y, %x 394 %xor = xor i32 %or1, %or2 395 ret i32 %xor 396} 397 398; (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2) 399define i8 @test23(i8 %A) { 400; CHECK-LABEL: @test23( 401; CHECK-NEXT: ret i8 -1 402; 403 %B = or i8 %A, -2 404 %C = xor i8 %B, 13 405 %D = or i8 %C, 1 406 %E = xor i8 %D, 12 407 ret i8 %E 408} 409 410define i8 @test23v(<2 x i8> %A) { 411; CHECK-LABEL: @test23v( 412; CHECK-NEXT: ret i8 -1 413; 414 %B = or <2 x i8> %A, <i8 -2, i8 0> 415 %CV = xor <2 x i8> %B, <i8 13, i8 13> 416 %C = extractelement <2 x i8> %CV, i32 0 417 %D = or i8 %C, 1 418 %E = xor i8 %D, 12 419 ret i8 %E 420} 421