1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s 3 4 ; https://bugs.llvm.org/show_bug.cgi?id=37104 5 6 define i8 @out8(i8 %x, i8 %y, i8 %mask) { 7 ; CHECK-LABEL: out8: 8 ; CHECK: // %bb.0: 9 ; CHECK-NEXT: and w8, w0, w2 10 ; CHECK-NEXT: bic w9, w1, w2 11 ; CHECK-NEXT: orr w0, w8, w9 12 ; CHECK-NEXT: ret 13 %mx = and i8 %x, %mask 14 %notmask = xor i8 %mask, -1 15 %my = and i8 %y, %notmask 16 %r = or i8 %mx, %my 17 ret i8 %r 18 } 19 20 define i16 @out16(i16 %x, i16 %y, i16 %mask) { 21 ; CHECK-LABEL: out16: 22 ; CHECK: // %bb.0: 23 ; CHECK-NEXT: and w8, w0, w2 24 ; CHECK-NEXT: bic w9, w1, w2 25 ; CHECK-NEXT: orr w0, w8, w9 26 ; CHECK-NEXT: ret 27 %mx = and i16 %x, %mask 28 %notmask = xor i16 %mask, -1 29 %my = and i16 %y, %notmask 30 %r = or i16 %mx, %my 31 ret i16 %r 32 } 33 34 define i32 @out32(i32 %x, i32 %y, i32 %mask) { 35 ; CHECK-LABEL: out32: 36 ; CHECK: // %bb.0: 37 ; CHECK-NEXT: and w8, w0, w2 38 ; CHECK-NEXT: bic w9, w1, w2 39 ; CHECK-NEXT: orr w0, w8, w9 40 ; CHECK-NEXT: ret 41 %mx = and i32 %x, %mask 42 %notmask = xor i32 %mask, -1 43 %my = and i32 %y, %notmask 44 %r = or i32 %mx, %my 45 ret i32 %r 46 } 47 48 define i64 @out64(i64 %x, i64 %y, i64 %mask) { 49 ; CHECK-LABEL: out64: 50 ; CHECK: // %bb.0: 51 ; CHECK-NEXT: and x8, x0, x2 52 ; CHECK-NEXT: bic x9, x1, x2 53 ; CHECK-NEXT: orr x0, x8, x9 54 ; CHECK-NEXT: ret 55 %mx = and i64 %x, %mask 56 %notmask = xor i64 %mask, -1 57 %my = and i64 %y, %notmask 58 %r = or i64 %mx, %my 59 ret i64 %r 60 } 61 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 62 ; Should be the same as the previous one. 63 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 64 65 define i8 @in8(i8 %x, i8 %y, i8 %mask) { 66 ; CHECK-LABEL: in8: 67 ; CHECK: // %bb.0: 68 ; CHECK-NEXT: and w8, w0, w2 69 ; CHECK-NEXT: bic w9, w1, w2 70 ; CHECK-NEXT: orr w0, w8, w9 71 ; CHECK-NEXT: ret 72 %n0 = xor i8 %x, %y 73 %n1 = and i8 %n0, %mask 74 %r = xor i8 %n1, %y 75 ret i8 %r 76 } 77 78 define i16 @in16(i16 %x, i16 %y, i16 %mask) { 79 ; CHECK-LABEL: in16: 80 ; CHECK: // %bb.0: 81 ; CHECK-NEXT: and w8, w0, w2 82 ; CHECK-NEXT: bic w9, w1, w2 83 ; CHECK-NEXT: orr w0, w8, w9 84 ; CHECK-NEXT: ret 85 %n0 = xor i16 %x, %y 86 %n1 = and i16 %n0, %mask 87 %r = xor i16 %n1, %y 88 ret i16 %r 89 } 90 91 define i32 @in32(i32 %x, i32 %y, i32 %mask) { 92 ; CHECK-LABEL: in32: 93 ; CHECK: // %bb.0: 94 ; CHECK-NEXT: bic w8, w1, w2 95 ; CHECK-NEXT: and w9, w0, w2 96 ; CHECK-NEXT: orr w0, w9, w8 97 ; CHECK-NEXT: ret 98 %n0 = xor i32 %x, %y 99 %n1 = and i32 %n0, %mask 100 %r = xor i32 %n1, %y 101 ret i32 %r 102 } 103 104 define i64 @in64(i64 %x, i64 %y, i64 %mask) { 105 ; CHECK-LABEL: in64: 106 ; CHECK: // %bb.0: 107 ; CHECK-NEXT: bic x8, x1, x2 108 ; CHECK-NEXT: and x9, x0, x2 109 ; CHECK-NEXT: orr x0, x9, x8 110 ; CHECK-NEXT: ret 111 %n0 = xor i64 %x, %y 112 %n1 = and i64 %n0, %mask 113 %r = xor i64 %n1, %y 114 ret i64 %r 115 } 116 ; ============================================================================ ; 117 ; Commutativity tests. 118 ; ============================================================================ ; 119 define i32 @in_commutativity_0_0_1(i32 %x, i32 %y, i32 %mask) { 120 ; CHECK-LABEL: in_commutativity_0_0_1: 121 ; CHECK: // %bb.0: 122 ; CHECK-NEXT: bic w8, w1, w2 123 ; CHECK-NEXT: and w9, w0, w2 124 ; CHECK-NEXT: orr w0, w9, w8 125 ; CHECK-NEXT: ret 126 %n0 = xor i32 %x, %y 127 %n1 = and i32 %mask, %n0 ; swapped 128 %r = xor i32 %n1, %y 129 ret i32 %r 130 } 131 define i32 @in_commutativity_0_1_0(i32 %x, i32 %y, i32 %mask) { 132 ; CHECK-LABEL: in_commutativity_0_1_0: 133 ; CHECK: // %bb.0: 134 ; CHECK-NEXT: bic w8, w1, w2 135 ; CHECK-NEXT: and w9, w0, w2 136 ; CHECK-NEXT: orr w0, w9, w8 137 ; CHECK-NEXT: ret 138 %n0 = xor i32 %x, %y 139 %n1 = and i32 %n0, %mask 140 %r = xor i32 %y, %n1 ; swapped 141 ret i32 %r 142 } 143 define i32 @in_commutativity_0_1_1(i32 %x, i32 %y, i32 %mask) { 144 ; CHECK-LABEL: in_commutativity_0_1_1: 145 ; CHECK: // %bb.0: 146 ; CHECK-NEXT: bic w8, w1, w2 147 ; CHECK-NEXT: and w9, w0, w2 148 ; CHECK-NEXT: orr w0, w9, w8 149 ; CHECK-NEXT: ret 150 %n0 = xor i32 %x, %y 151 %n1 = and i32 %mask, %n0 ; swapped 152 %r = xor i32 %y, %n1 ; swapped 153 ret i32 %r 154 } 155 define i32 @in_commutativity_1_0_0(i32 %x, i32 %y, i32 %mask) { 156 ; CHECK-LABEL: in_commutativity_1_0_0: 157 ; CHECK: // %bb.0: 158 ; CHECK-NEXT: bic w8, w0, w2 159 ; CHECK-NEXT: and w9, w1, w2 160 ; CHECK-NEXT: orr w0, w9, w8 161 ; CHECK-NEXT: ret 162 %n0 = xor i32 %x, %y 163 %n1 = and i32 %n0, %mask 164 %r = xor i32 %n1, %x ; %x instead of %y 165 ret i32 %r 166 } 167 define i32 @in_commutativity_1_0_1(i32 %x, i32 %y, i32 %mask) { 168 ; CHECK-LABEL: in_commutativity_1_0_1: 169 ; CHECK: // %bb.0: 170 ; CHECK-NEXT: bic w8, w0, w2 171 ; CHECK-NEXT: and w9, w1, w2 172 ; CHECK-NEXT: orr w0, w9, w8 173 ; CHECK-NEXT: ret 174 %n0 = xor i32 %x, %y 175 %n1 = and i32 %mask, %n0 ; swapped 176 %r = xor i32 %n1, %x ; %x instead of %y 177 ret i32 %r 178 } 179 define i32 @in_commutativity_1_1_0(i32 %x, i32 %y, i32 %mask) { 180 ; CHECK-LABEL: in_commutativity_1_1_0: 181 ; CHECK: // %bb.0: 182 ; CHECK-NEXT: bic w8, w0, w2 183 ; CHECK-NEXT: and w9, w1, w2 184 ; CHECK-NEXT: orr w0, w9, w8 185 ; CHECK-NEXT: ret 186 %n0 = xor i32 %x, %y 187 %n1 = and i32 %n0, %mask 188 %r = xor i32 %x, %n1 ; swapped, %x instead of %y 189 ret i32 %r 190 } 191 define i32 @in_commutativity_1_1_1(i32 %x, i32 %y, i32 %mask) { 192 ; CHECK-LABEL: in_commutativity_1_1_1: 193 ; CHECK: // %bb.0: 194 ; CHECK-NEXT: bic w8, w0, w2 195 ; CHECK-NEXT: and w9, w1, w2 196 ; CHECK-NEXT: orr w0, w9, w8 197 ; CHECK-NEXT: ret 198 %n0 = xor i32 %x, %y 199 %n1 = and i32 %mask, %n0 ; swapped 200 %r = xor i32 %x, %n1 ; swapped, %x instead of %y 201 ret i32 %r 202 } 203 ; ============================================================================ ; 204 ; Y is an 'and' too. 205 ; ============================================================================ ; 206 define i32 @in_complex_y0(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) { 207 ; CHECK-LABEL: in_complex_y0: 208 ; CHECK: // %bb.0: 209 ; CHECK-NEXT: and w8, w1, w2 210 ; CHECK-NEXT: and w9, w0, w3 211 ; CHECK-NEXT: bic w8, w8, w3 212 ; CHECK-NEXT: orr w0, w9, w8 213 ; CHECK-NEXT: ret 214 %y = and i32 %y_hi, %y_low 215 %n0 = xor i32 %x, %y 216 %n1 = and i32 %n0, %mask 217 %r = xor i32 %n1, %y 218 ret i32 %r 219 } 220 define i32 @in_complex_y1(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) { 221 ; CHECK-LABEL: in_complex_y1: 222 ; CHECK: // %bb.0: 223 ; CHECK-NEXT: and w8, w1, w2 224 ; CHECK-NEXT: and w9, w0, w3 225 ; CHECK-NEXT: bic w8, w8, w3 226 ; CHECK-NEXT: orr w0, w9, w8 227 ; CHECK-NEXT: ret 228 %y = and i32 %y_hi, %y_low 229 %n0 = xor i32 %x, %y 230 %n1 = and i32 %n0, %mask 231 %r = xor i32 %y, %n1 232 ret i32 %r 233 } 234 ; ============================================================================ ; 235 ; M is an 'xor' too. 236 ; ============================================================================ ; 237 define i32 @in_complex_m0(i32 %x, i32 %y, i32 %m_a, i32 %m_b) { 238 ; CHECK-LABEL: in_complex_m0: 239 ; CHECK: // %bb.0: 240 ; CHECK-NEXT: eor w8, w2, w3 241 ; CHECK-NEXT: bic w9, w1, w8 242 ; CHECK-NEXT: and w8, w0, w8 243 ; CHECK-NEXT: orr w0, w8, w9 244 ; CHECK-NEXT: ret 245 %mask = xor i32 %m_a, %m_b 246 %n0 = xor i32 %x, %y 247 %n1 = and i32 %n0, %mask 248 %r = xor i32 %n1, %y 249 ret i32 %r 250 } 251 define i32 @in_complex_m1(i32 %x, i32 %y, i32 %m_a, i32 %m_b) { 252 ; CHECK-LABEL: in_complex_m1: 253 ; CHECK: // %bb.0: 254 ; CHECK-NEXT: eor w8, w2, w3 255 ; CHECK-NEXT: bic w9, w1, w8 256 ; CHECK-NEXT: and w8, w0, w8 257 ; CHECK-NEXT: orr w0, w8, w9 258 ; CHECK-NEXT: ret 259 %mask = xor i32 %m_a, %m_b 260 %n0 = xor i32 %x, %y 261 %n1 = and i32 %mask, %n0 262 %r = xor i32 %n1, %y 263 ret i32 %r 264 } 265 ; ============================================================================ ; 266 ; Both Y and M are complex. 267 ; ============================================================================ ; 268 define i32 @in_complex_y0_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { 269 ; CHECK-LABEL: in_complex_y0_m0: 270 ; CHECK: // %bb.0: 271 ; CHECK-NEXT: and w8, w1, w2 272 ; CHECK-NEXT: eor w9, w3, w4 273 ; CHECK-NEXT: bic w8, w8, w9 274 ; CHECK-NEXT: and w9, w0, w9 275 ; CHECK-NEXT: orr w0, w9, w8 276 ; CHECK-NEXT: ret 277 %y = and i32 %y_hi, %y_low 278 %mask = xor i32 %m_a, %m_b 279 %n0 = xor i32 %x, %y 280 %n1 = and i32 %n0, %mask 281 %r = xor i32 %n1, %y 282 ret i32 %r 283 } 284 define i32 @in_complex_y1_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { 285 ; CHECK-LABEL: in_complex_y1_m0: 286 ; CHECK: // %bb.0: 287 ; CHECK-NEXT: and w8, w1, w2 288 ; CHECK-NEXT: eor w9, w3, w4 289 ; CHECK-NEXT: bic w8, w8, w9 290 ; CHECK-NEXT: and w9, w0, w9 291 ; CHECK-NEXT: orr w0, w9, w8 292 ; CHECK-NEXT: ret 293 %y = and i32 %y_hi, %y_low 294 %mask = xor i32 %m_a, %m_b 295 %n0 = xor i32 %x, %y 296 %n1 = and i32 %n0, %mask 297 %r = xor i32 %y, %n1 298 ret i32 %r 299 } 300 define i32 @in_complex_y0_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { 301 ; CHECK-LABEL: in_complex_y0_m1: 302 ; CHECK: // %bb.0: 303 ; CHECK-NEXT: and w8, w1, w2 304 ; CHECK-NEXT: eor w9, w3, w4 305 ; CHECK-NEXT: bic w8, w8, w9 306 ; CHECK-NEXT: and w9, w0, w9 307 ; CHECK-NEXT: orr w0, w9, w8 308 ; CHECK-NEXT: ret 309 %y = and i32 %y_hi, %y_low 310 %mask = xor i32 %m_a, %m_b 311 %n0 = xor i32 %x, %y 312 %n1 = and i32 %mask, %n0 313 %r = xor i32 %n1, %y 314 ret i32 %r 315 } 316 define i32 @in_complex_y1_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { 317 ; CHECK-LABEL: in_complex_y1_m1: 318 ; CHECK: // %bb.0: 319 ; CHECK-NEXT: and w8, w1, w2 320 ; CHECK-NEXT: eor w9, w3, w4 321 ; CHECK-NEXT: bic w8, w8, w9 322 ; CHECK-NEXT: and w9, w0, w9 323 ; CHECK-NEXT: orr w0, w9, w8 324 ; CHECK-NEXT: ret 325 %y = and i32 %y_hi, %y_low 326 %mask = xor i32 %m_a, %m_b 327 %n0 = xor i32 %x, %y 328 %n1 = and i32 %mask, %n0 329 %r = xor i32 %y, %n1 330 ret i32 %r 331 } 332 ; ============================================================================ ; 333 ; Various cases with %x and/or %y being a constant 334 ; ============================================================================ ; 335 define i32 @out_constant_varx_mone(i32 %x, i32 %y, i32 %mask) { 336 ; CHECK-LABEL: out_constant_varx_mone: 337 ; CHECK: // %bb.0: 338 ; CHECK-NEXT: and w8, w2, w0 339 ; CHECK-NEXT: orn w0, w8, w2 340 ; CHECK-NEXT: ret 341 %notmask = xor i32 %mask, -1 342 %mx = and i32 %mask, %x 343 %my = and i32 %notmask, -1 344 %r = or i32 %mx, %my 345 ret i32 %r 346 } 347 define i32 @in_constant_varx_mone(i32 %x, i32 %y, i32 %mask) { 348 ; CHECK-LABEL: in_constant_varx_mone: 349 ; CHECK: // %bb.0: 350 ; CHECK-NEXT: bic w8, w2, w0 351 ; CHECK-NEXT: mvn w0, w8 352 ; CHECK-NEXT: ret 353 %n0 = xor i32 %x, -1 ; %x 354 %n1 = and i32 %n0, %mask 355 %r = xor i32 %n1, -1 356 ret i32 %r 357 } 358 ; This is not a canonical form. Testing for completeness only. 359 define i32 @out_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) { 360 ; CHECK-LABEL: out_constant_varx_mone_invmask: 361 ; CHECK: // %bb.0: 362 ; CHECK-NEXT: bic w8, w0, w2 363 ; CHECK-NEXT: orr w0, w8, w2 364 ; CHECK-NEXT: ret 365 %notmask = xor i32 %mask, -1 366 %mx = and i32 %notmask, %x 367 %my = and i32 %mask, -1 368 %r = or i32 %mx, %my 369 ret i32 %r 370 } 371 ; This is not a canonical form. Testing for completeness only. 372 define i32 @in_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) { 373 ; CHECK-LABEL: in_constant_varx_mone_invmask: 374 ; CHECK: // %bb.0: 375 ; CHECK-NEXT: mvn w8, w0 376 ; CHECK-NEXT: bic w8, w8, w2 377 ; CHECK-NEXT: mvn w0, w8 378 ; CHECK-NEXT: ret 379 %notmask = xor i32 %mask, -1 380 %n0 = xor i32 %x, -1 ; %x 381 %n1 = and i32 %n0, %notmask 382 %r = xor i32 %n1, -1 383 ret i32 %r 384 } 385 define i32 @out_constant_varx_42(i32 %x, i32 %y, i32 %mask) { 386 ; CHECK-LABEL: out_constant_varx_42: 387 ; CHECK: // %bb.0: 388 ; CHECK-NEXT: mov w9, #42 389 ; CHECK-NEXT: and w8, w2, w0 390 ; CHECK-NEXT: bic w9, w9, w2 391 ; CHECK-NEXT: orr w0, w8, w9 392 ; CHECK-NEXT: ret 393 %notmask = xor i32 %mask, -1 394 %mx = and i32 %mask, %x 395 %my = and i32 %notmask, 42 396 %r = or i32 %mx, %my 397 ret i32 %r 398 } 399 define i32 @in_constant_varx_42(i32 %x, i32 %y, i32 %mask) { 400 ; CHECK-LABEL: in_constant_varx_42: 401 ; CHECK: // %bb.0: 402 ; CHECK-NEXT: mov w8, #42 403 ; CHECK-NEXT: bic w8, w8, w2 404 ; CHECK-NEXT: and w9, w0, w2 405 ; CHECK-NEXT: orr w0, w9, w8 406 ; CHECK-NEXT: ret 407 %n0 = xor i32 %x, 42 ; %x 408 %n1 = and i32 %n0, %mask 409 %r = xor i32 %n1, 42 410 ret i32 %r 411 } 412 ; This is not a canonical form. Testing for completeness only. 413 define i32 @out_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) { 414 ; CHECK-LABEL: out_constant_varx_42_invmask: 415 ; CHECK: // %bb.0: 416 ; CHECK-NEXT: mov w9, #42 417 ; CHECK-NEXT: bic w8, w0, w2 418 ; CHECK-NEXT: and w9, w2, w9 419 ; CHECK-NEXT: orr w0, w8, w9 420 ; CHECK-NEXT: ret 421 %notmask = xor i32 %mask, -1 422 %mx = and i32 %notmask, %x 423 %my = and i32 %mask, 42 424 %r = or i32 %mx, %my 425 ret i32 %r 426 } 427 ; This is not a canonical form. Testing for completeness only. 428 define i32 @in_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) { 429 ; CHECK-LABEL: in_constant_varx_42_invmask: 430 ; CHECK: // %bb.0: 431 ; CHECK-NEXT: mov w8, #42 432 ; CHECK-NEXT: and w8, w2, w8 433 ; CHECK-NEXT: bic w9, w0, w2 434 ; CHECK-NEXT: orr w0, w9, w8 435 ; CHECK-NEXT: ret 436 %notmask = xor i32 %mask, -1 437 %n0 = xor i32 %x, 42 ; %x 438 %n1 = and i32 %n0, %notmask 439 %r = xor i32 %n1, 42 440 ret i32 %r 441 } 442 define i32 @out_constant_mone_vary(i32 %x, i32 %y, i32 %mask) { 443 ; CHECK-LABEL: out_constant_mone_vary: 444 ; CHECK: // %bb.0: 445 ; CHECK-NEXT: bic w8, w1, w2 446 ; CHECK-NEXT: orr w0, w2, w8 447 ; CHECK-NEXT: ret 448 %notmask = xor i32 %mask, -1 449 %mx = and i32 %mask, -1 450 %my = and i32 %notmask, %y 451 %r = or i32 %mx, %my 452 ret i32 %r 453 } 454 define i32 @in_constant_mone_vary(i32 %x, i32 %y, i32 %mask) { 455 ; CHECK-LABEL: in_constant_mone_vary: 456 ; CHECK: // %bb.0: 457 ; CHECK-NEXT: bic w8, w2, w1 458 ; CHECK-NEXT: eor w0, w8, w1 459 ; CHECK-NEXT: ret 460 %n0 = xor i32 -1, %y ; %x 461 %n1 = and i32 %n0, %mask 462 %r = xor i32 %n1, %y 463 ret i32 %r 464 } 465 ; This is not a canonical form. Testing for completeness only. 466 define i32 @out_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) { 467 ; CHECK-LABEL: out_constant_mone_vary_invmask: 468 ; CHECK: // %bb.0: 469 ; CHECK-NEXT: and w8, w2, w1 470 ; CHECK-NEXT: orn w0, w8, w2 471 ; CHECK-NEXT: ret 472 %notmask = xor i32 %mask, -1 473 %mx = and i32 %notmask, -1 474 %my = and i32 %mask, %y 475 %r = or i32 %mx, %my 476 ret i32 %r 477 } 478 ; This is not a canonical form. Testing for completeness only. 479 define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) { 480 ; CHECK-LABEL: in_constant_mone_vary_invmask: 481 ; CHECK: // %bb.0: 482 ; CHECK-NEXT: mvn w8, w1 483 ; CHECK-NEXT: bic w8, w8, w2 484 ; CHECK-NEXT: eor w0, w8, w1 485 ; CHECK-NEXT: ret 486 %notmask = xor i32 %mask, -1 487 %n0 = xor i32 -1, %y ; %x 488 %n1 = and i32 %n0, %notmask 489 %r = xor i32 %n1, %y 490 ret i32 %r 491 } 492 define i32 @out_constant_42_vary(i32 %x, i32 %y, i32 %mask) { 493 ; CHECK-LABEL: out_constant_42_vary: 494 ; CHECK: // %bb.0: 495 ; CHECK-NEXT: mov w8, #42 496 ; CHECK-NEXT: and w8, w2, w8 497 ; CHECK-NEXT: bic w9, w1, w2 498 ; CHECK-NEXT: orr w0, w8, w9 499 ; CHECK-NEXT: ret 500 %notmask = xor i32 %mask, -1 501 %mx = and i32 %mask, 42 502 %my = and i32 %notmask, %y 503 %r = or i32 %mx, %my 504 ret i32 %r 505 } 506 define i32 @in_constant_42_vary(i32 %x, i32 %y, i32 %mask) { 507 ; CHECK-LABEL: in_constant_42_vary: 508 ; CHECK: // %bb.0: 509 ; CHECK-NEXT: mov w9, #42 510 ; CHECK-NEXT: bic w8, w1, w2 511 ; CHECK-NEXT: and w9, w2, w9 512 ; CHECK-NEXT: orr w0, w9, w8 513 ; CHECK-NEXT: ret 514 %n0 = xor i32 42, %y ; %x 515 %n1 = and i32 %n0, %mask 516 %r = xor i32 %n1, %y 517 ret i32 %r 518 } 519 ; This is not a canonical form. Testing for completeness only. 520 define i32 @out_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) { 521 ; CHECK-LABEL: out_constant_42_vary_invmask: 522 ; CHECK: // %bb.0: 523 ; CHECK-NEXT: mov w8, #42 524 ; CHECK-NEXT: bic w8, w8, w2 525 ; CHECK-NEXT: and w9, w2, w1 526 ; CHECK-NEXT: orr w0, w8, w9 527 ; CHECK-NEXT: ret 528 %notmask = xor i32 %mask, -1 529 %mx = and i32 %notmask, 42 530 %my = and i32 %mask, %y 531 %r = or i32 %mx, %my 532 ret i32 %r 533 } 534 ; This is not a canonical form. Testing for completeness only. 535 define i32 @in_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) { 536 ; CHECK-LABEL: in_constant_42_vary_invmask: 537 ; CHECK: // %bb.0: 538 ; CHECK-NEXT: mov w9, #42 539 ; CHECK-NEXT: and w8, w1, w2 540 ; CHECK-NEXT: bic w9, w9, w2 541 ; CHECK-NEXT: orr w0, w9, w8 542 ; CHECK-NEXT: ret 543 %notmask = xor i32 %mask, -1 544 %n0 = xor i32 42, %y ; %x 545 %n1 = and i32 %n0, %notmask 546 %r = xor i32 %n1, %y 547 ret i32 %r 548 } 549 ; ============================================================================ ; 550 ; Negative tests. Should not be folded. 551 ; ============================================================================ ; 552 ; Multi-use tests. 553 declare void @use32(i32) nounwind 554 define i32 @in_multiuse_A(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind { 555 ; CHECK-LABEL: in_multiuse_A: 556 ; CHECK: // %bb.0: 557 ; CHECK-NEXT: str x20, [sp, #-32]! // 8-byte Folded Spill 558 ; CHECK-NEXT: eor w8, w0, w1 559 ; CHECK-NEXT: and w20, w8, w3 560 ; CHECK-NEXT: mov w0, w20 561 ; CHECK-NEXT: stp x19, x30, [sp, #16] // 8-byte Folded Spill 562 ; CHECK-NEXT: mov w19, w1 563 ; CHECK-NEXT: bl use32 564 ; CHECK-NEXT: eor w0, w20, w19 565 ; CHECK-NEXT: ldp x19, x30, [sp, #16] // 8-byte Folded Reload 566 ; CHECK-NEXT: ldr x20, [sp], #32 // 8-byte Folded Reload 567 ; CHECK-NEXT: ret 568 %n0 = xor i32 %x, %y 569 %n1 = and i32 %n0, %mask 570 call void @use32(i32 %n1) 571 %r = xor i32 %n1, %y 572 ret i32 %r 573 } 574 define i32 @in_multiuse_B(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind { 575 ; CHECK-LABEL: in_multiuse_B: 576 ; CHECK: // %bb.0: 577 ; CHECK-NEXT: str x20, [sp, #-32]! // 8-byte Folded Spill 578 ; CHECK-NEXT: eor w0, w0, w1 579 ; CHECK-NEXT: stp x19, x30, [sp, #16] // 8-byte Folded Spill 580 ; CHECK-NEXT: mov w19, w1 581 ; CHECK-NEXT: and w20, w0, w3 582 ; CHECK-NEXT: bl use32 583 ; CHECK-NEXT: eor w0, w20, w19 584 ; CHECK-NEXT: ldp x19, x30, [sp, #16] // 8-byte Folded Reload 585 ; CHECK-NEXT: ldr x20, [sp], #32 // 8-byte Folded Reload 586 ; CHECK-NEXT: ret 587 %n0 = xor i32 %x, %y 588 %n1 = and i32 %n0, %mask 589 call void @use32(i32 %n0) 590 %r = xor i32 %n1, %y 591 ret i32 %r 592 } 593 ; Various bad variants 594 define i32 @n0_badmask(i32 %x, i32 %y, i32 %mask, i32 %mask2) { 595 ; CHECK-LABEL: n0_badmask: 596 ; CHECK: // %bb.0: 597 ; CHECK-NEXT: and w8, w0, w2 598 ; CHECK-NEXT: bic w9, w1, w3 599 ; CHECK-NEXT: orr w0, w8, w9 600 ; CHECK-NEXT: ret 601 %mx = and i32 %x, %mask 602 %notmask = xor i32 %mask2, -1 ; %mask2 instead of %mask 603 %my = and i32 %y, %notmask 604 %r = or i32 %mx, %my 605 ret i32 %r 606 } 607 define i32 @n0_badxor(i32 %x, i32 %y, i32 %mask) { 608 ; CHECK-LABEL: n0_badxor: 609 ; CHECK: // %bb.0: 610 ; CHECK-NEXT: eor w9, w2, #0x1 611 ; CHECK-NEXT: and w8, w0, w2 612 ; CHECK-NEXT: and w9, w1, w9 613 ; CHECK-NEXT: orr w0, w8, w9 614 ; CHECK-NEXT: ret 615 %mx = and i32 %x, %mask 616 %notmask = xor i32 %mask, 1 ; instead of -1 617 %my = and i32 %y, %notmask 618 %r = or i32 %mx, %my 619 ret i32 %r 620 } 621 define i32 @n1_thirdvar(i32 %x, i32 %y, i32 %z, i32 %mask) { 622 ; CHECK-LABEL: n1_thirdvar: 623 ; CHECK: // %bb.0: 624 ; CHECK-NEXT: eor w8, w0, w1 625 ; CHECK-NEXT: and w8, w8, w3 626 ; CHECK-NEXT: eor w0, w8, w2 627 ; CHECK-NEXT: ret 628 %n0 = xor i32 %x, %y 629 %n1 = and i32 %n0, %mask 630 %r = xor i32 %n1, %z ; instead of %y 631 ret i32 %r 632 } 633