1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=aarch64 -o - | FileCheck %s 3; RUN: llc < %s -mtriple=aarch64_be -o - | FileCheck %s --check-prefix=CHECKBE 4 5define i64 @load32_and16_and(ptr %p, i64 %y) { 6; CHECK-LABEL: load32_and16_and: 7; CHECK: // %bb.0: 8; CHECK-NEXT: ldr w8, [x0] 9; CHECK-NEXT: and w8, w1, w8 10; CHECK-NEXT: and x0, x8, #0xffff 11; CHECK-NEXT: ret 12; 13; CHECKBE-LABEL: load32_and16_and: 14; CHECKBE: // %bb.0: 15; CHECKBE-NEXT: ldr w8, [x0] 16; CHECKBE-NEXT: and w8, w1, w8 17; CHECKBE-NEXT: and x0, x8, #0xffff 18; CHECKBE-NEXT: ret 19 %x = load i32, ptr %p, align 4 20 %xz = zext i32 %x to i64 21 %ym = and i64 %y, 65535 22 %r = and i64 %ym, %xz 23 ret i64 %r 24} 25 26define i64 @load32_and16_andr(ptr %p, i64 %y) { 27; CHECK-LABEL: load32_and16_andr: 28; CHECK: // %bb.0: 29; CHECK-NEXT: ldr w8, [x0] 30; CHECK-NEXT: and w8, w1, w8 31; CHECK-NEXT: and x0, x8, #0xffff 32; CHECK-NEXT: ret 33; 34; CHECKBE-LABEL: load32_and16_andr: 35; CHECKBE: // %bb.0: 36; CHECKBE-NEXT: ldr w8, [x0] 37; CHECKBE-NEXT: and w8, w1, w8 38; CHECKBE-NEXT: and x0, x8, #0xffff 39; CHECKBE-NEXT: ret 40 %x = load i32, ptr %p, align 4 41 %xz = zext i32 %x to i64 42 %a = and i64 %y, %xz 43 %r = and i64 %a, 65535 44 ret i64 %r 45} 46 47define i64 @load32_and16_and_sext(ptr %p, i64 %y) { 48; CHECK-LABEL: load32_and16_and_sext: 49; CHECK: // %bb.0: 50; CHECK-NEXT: ldr w8, [x0] 51; CHECK-NEXT: and w8, w1, w8 52; CHECK-NEXT: and x0, x8, #0xffff 53; CHECK-NEXT: ret 54; 55; CHECKBE-LABEL: load32_and16_and_sext: 56; CHECKBE: // %bb.0: 57; CHECKBE-NEXT: ldr w8, [x0] 58; CHECKBE-NEXT: and w8, w1, w8 59; CHECKBE-NEXT: and x0, x8, #0xffff 60; CHECKBE-NEXT: ret 61 %x = load i32, ptr %p, align 4 62 %xz = sext i32 %x to i64 63 %a = and i64 %y, %xz 64 %r = and i64 %a, 65535 65 ret i64 %r 66} 67 68define i64 @load32_and16_or(ptr %p, i64 %y) { 69; CHECK-LABEL: load32_and16_or: 70; CHECK: // %bb.0: 71; CHECK-NEXT: ldr w8, [x0] 72; CHECK-NEXT: orr w8, w1, w8 73; CHECK-NEXT: and x0, x8, #0xffff 74; CHECK-NEXT: ret 75; 76; CHECKBE-LABEL: load32_and16_or: 77; CHECKBE: // %bb.0: 78; CHECKBE-NEXT: ldr w8, [x0] 79; CHECKBE-NEXT: orr w8, w1, w8 80; CHECKBE-NEXT: and x0, x8, #0xffff 81; CHECKBE-NEXT: ret 82 %x = load i32, ptr %p, align 4 83 %xz = zext i32 %x to i64 84 %a = or i64 %y, %xz 85 %r = and i64 %a, 65535 86 ret i64 %r 87} 88 89define i64 @load32_and16_orr(ptr %p, i64 %y) { 90; CHECK-LABEL: load32_and16_orr: 91; CHECK: // %bb.0: 92; CHECK-NEXT: ldr w8, [x0] 93; CHECK-NEXT: and x9, x1, #0xffff 94; CHECK-NEXT: orr x0, x9, x8 95; CHECK-NEXT: ret 96; 97; CHECKBE-LABEL: load32_and16_orr: 98; CHECKBE: // %bb.0: 99; CHECKBE-NEXT: ldr w8, [x0] 100; CHECKBE-NEXT: and x9, x1, #0xffff 101; CHECKBE-NEXT: orr x0, x9, x8 102; CHECKBE-NEXT: ret 103 %x = load i32, ptr %p, align 4 104 %xz = zext i32 %x to i64 105 %ym = and i64 %y, 65535 106 %r = or i64 %ym, %xz 107 ret i64 %r 108} 109 110define i64 @load32_and16_xorm1(ptr %p) { 111; CHECK-LABEL: load32_and16_xorm1: 112; CHECK: // %bb.0: 113; CHECK-NEXT: ldr w8, [x0] 114; CHECK-NEXT: mvn w8, w8 115; CHECK-NEXT: and x0, x8, #0xffff 116; CHECK-NEXT: ret 117; 118; CHECKBE-LABEL: load32_and16_xorm1: 119; CHECKBE: // %bb.0: 120; CHECKBE-NEXT: ldr w8, [x0] 121; CHECKBE-NEXT: mvn w8, w8 122; CHECKBE-NEXT: and x0, x8, #0xffff 123; CHECKBE-NEXT: ret 124 %x = load i32, ptr %p, align 4 125 %xz = zext i32 %x to i64 126 %a = xor i64 %xz, -1 127 %r = and i64 %a, 65535 128 ret i64 %r 129} 130 131define i64 @load64_and16(ptr %p, i128 %y) { 132; CHECK-LABEL: load64_and16: 133; CHECK: // %bb.0: 134; CHECK-NEXT: ldrh w8, [x0] 135; CHECK-NEXT: and x0, x2, x8 136; CHECK-NEXT: ret 137; 138; CHECKBE-LABEL: load64_and16: 139; CHECKBE: // %bb.0: 140; CHECKBE-NEXT: ldrh w8, [x0, #6] 141; CHECKBE-NEXT: and x0, x3, x8 142; CHECKBE-NEXT: ret 143 %x = load i64, ptr %p, align 4 144 %xz = zext i64 %x to i128 145 %a = and i128 %y, %xz 146 %t = trunc i128 %a to i64 147 %r = and i64 %t, 65535 148 ret i64 %r 149} 150 151define i64 @load16_and16(ptr %p, i64 %y) { 152; CHECK-LABEL: load16_and16: 153; CHECK: // %bb.0: 154; CHECK-NEXT: ldrh w8, [x0] 155; CHECK-NEXT: and x0, x1, x8 156; CHECK-NEXT: ret 157; 158; CHECKBE-LABEL: load16_and16: 159; CHECKBE: // %bb.0: 160; CHECKBE-NEXT: ldrh w8, [x0] 161; CHECKBE-NEXT: and x0, x1, x8 162; CHECKBE-NEXT: ret 163 %x = load i16, ptr %p, align 4 164 %xz = zext i16 %x to i64 165 %a = and i64 %y, %xz 166 %r = and i64 %a, 65535 167 ret i64 %r 168} 169 170define i64 @load16_and8(ptr %p, i64 %y) { 171; CHECK-LABEL: load16_and8: 172; CHECK: // %bb.0: 173; CHECK-NEXT: ldrh w8, [x0] 174; CHECK-NEXT: and w8, w1, w8 175; CHECK-NEXT: and x0, x8, #0xff 176; CHECK-NEXT: ret 177; 178; CHECKBE-LABEL: load16_and8: 179; CHECKBE: // %bb.0: 180; CHECKBE-NEXT: ldrh w8, [x0] 181; CHECKBE-NEXT: and w8, w1, w8 182; CHECKBE-NEXT: and x0, x8, #0xff 183; CHECKBE-NEXT: ret 184 %x = load i16, ptr %p, align 4 185 %xz = zext i16 %x to i64 186 %a = and i64 %y, %xz 187 %r = and i64 %a, 255 188 ret i64 %r 189} 190 191define i64 @load16_and7(ptr %p, i64 %y) { 192; CHECK-LABEL: load16_and7: 193; CHECK: // %bb.0: 194; CHECK-NEXT: ldrh w8, [x0] 195; CHECK-NEXT: and w8, w1, w8 196; CHECK-NEXT: and x0, x8, #0x7f 197; CHECK-NEXT: ret 198; 199; CHECKBE-LABEL: load16_and7: 200; CHECKBE: // %bb.0: 201; CHECKBE-NEXT: ldrh w8, [x0] 202; CHECKBE-NEXT: and w8, w1, w8 203; CHECKBE-NEXT: and x0, x8, #0x7f 204; CHECKBE-NEXT: ret 205 %x = load i16, ptr %p, align 4 206 %xz = zext i16 %x to i64 207 %a = and i64 %y, %xz 208 %r = and i64 %a, 127 209 ret i64 %r 210} 211 212define i64 @load8_and16(ptr %p, i64 %y) { 213; CHECK-LABEL: load8_and16: 214; CHECK: // %bb.0: 215; CHECK-NEXT: ldrb w8, [x0] 216; CHECK-NEXT: and x0, x1, x8 217; CHECK-NEXT: ret 218; 219; CHECKBE-LABEL: load8_and16: 220; CHECKBE: // %bb.0: 221; CHECKBE-NEXT: ldrb w8, [x0] 222; CHECKBE-NEXT: and x0, x1, x8 223; CHECKBE-NEXT: ret 224 %x = load i8, ptr %p, align 4 225 %xz = zext i8 %x to i64 226 %a = and i64 %y, %xz 227 %r = and i64 %a, 65535 228 ret i64 %r 229} 230 231define i64 @load8_and16_zext(ptr %p, i8 %y) { 232; CHECK-LABEL: load8_and16_zext: 233; CHECK: // %bb.0: 234; CHECK-NEXT: ldrb w8, [x0] 235; CHECK-NEXT: and w8, w1, w8 236; CHECK-NEXT: and x0, x8, #0xff 237; CHECK-NEXT: ret 238; 239; CHECKBE-LABEL: load8_and16_zext: 240; CHECKBE: // %bb.0: 241; CHECKBE-NEXT: ldrb w8, [x0] 242; CHECKBE-NEXT: and w8, w1, w8 243; CHECKBE-NEXT: and x0, x8, #0xff 244; CHECKBE-NEXT: ret 245 %x = load i8, ptr %p, align 4 246 %xz = zext i8 %x to i64 247 %yz = zext i8 %y to i64 248 %a = and i64 %yz, %xz 249 %r = and i64 %a, 65535 250 ret i64 %r 251} 252 253define i64 @load8_and16_sext(ptr %p, i8 %y) { 254; CHECK-LABEL: load8_and16_sext: 255; CHECK: // %bb.0: 256; CHECK-NEXT: ldrb w8, [x0] 257; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1 258; CHECK-NEXT: and x0, x1, x8 259; CHECK-NEXT: ret 260; 261; CHECKBE-LABEL: load8_and16_sext: 262; CHECKBE: // %bb.0: 263; CHECKBE-NEXT: ldrb w8, [x0] 264; CHECKBE-NEXT: // kill: def $w1 killed $w1 def $x1 265; CHECKBE-NEXT: and x0, x1, x8 266; CHECKBE-NEXT: ret 267 %x = load i8, ptr %p, align 4 268 %xz = zext i8 %x to i64 269 %yz = sext i8 %y to i64 270 %a = and i64 %yz, %xz 271 %r = and i64 %a, 65535 272 ret i64 %r 273} 274 275define i64 @load8_and16_or(ptr %p, i64 %y) { 276; CHECK-LABEL: load8_and16_or: 277; CHECK: // %bb.0: 278; CHECK-NEXT: ldrb w8, [x0] 279; CHECK-NEXT: orr w8, w1, w8 280; CHECK-NEXT: and x0, x8, #0xffff 281; CHECK-NEXT: ret 282; 283; CHECKBE-LABEL: load8_and16_or: 284; CHECKBE: // %bb.0: 285; CHECKBE-NEXT: ldrb w8, [x0] 286; CHECKBE-NEXT: orr w8, w1, w8 287; CHECKBE-NEXT: and x0, x8, #0xffff 288; CHECKBE-NEXT: ret 289 %x = load i8, ptr %p, align 4 290 %xz = zext i8 %x to i64 291 %a = or i64 %y, %xz 292 %r = and i64 %a, 65535 293 ret i64 %r 294} 295 296define i64 @load16_and8_manyext(ptr %p, i32 %y) { 297; CHECK-LABEL: load16_and8_manyext: 298; CHECK: // %bb.0: 299; CHECK-NEXT: ldrh w8, [x0] 300; CHECK-NEXT: and w8, w1, w8 301; CHECK-NEXT: and x0, x8, #0xff 302; CHECK-NEXT: ret 303; 304; CHECKBE-LABEL: load16_and8_manyext: 305; CHECKBE: // %bb.0: 306; CHECKBE-NEXT: ldrh w8, [x0] 307; CHECKBE-NEXT: and w8, w1, w8 308; CHECKBE-NEXT: and x0, x8, #0xff 309; CHECKBE-NEXT: ret 310 %x = load i16, ptr %p, align 4 311 %xz = zext i16 %x to i32 312 %a = and i32 %y, %xz 313 %az = zext i32 %a to i64 314 %r = and i64 %az, 255 315 ret i64 %r 316} 317 318define i64 @multiple_load(ptr %p, ptr %q) { 319; CHECK-LABEL: multiple_load: 320; CHECK: // %bb.0: 321; CHECK-NEXT: ldrh w8, [x0] 322; CHECK-NEXT: ldr w9, [x1] 323; CHECK-NEXT: and w8, w9, w8 324; CHECK-NEXT: and x0, x8, #0xff 325; CHECK-NEXT: ret 326; 327; CHECKBE-LABEL: multiple_load: 328; CHECKBE: // %bb.0: 329; CHECKBE-NEXT: ldrh w8, [x0] 330; CHECKBE-NEXT: ldr w9, [x1] 331; CHECKBE-NEXT: and w8, w9, w8 332; CHECKBE-NEXT: and x0, x8, #0xff 333; CHECKBE-NEXT: ret 334 %x = load i16, ptr %p, align 4 335 %xz = zext i16 %x to i64 336 %y = load i32, ptr %q, align 4 337 %yz = zext i32 %y to i64 338 %a = and i64 %yz, %xz 339 %r = and i64 %a, 255 340 ret i64 %r 341} 342 343define i64 @multiple_load_or(ptr %p, ptr %q) { 344; CHECK-LABEL: multiple_load_or: 345; CHECK: // %bb.0: 346; CHECK-NEXT: ldrh w8, [x0] 347; CHECK-NEXT: ldr w9, [x1] 348; CHECK-NEXT: orr w8, w9, w8 349; CHECK-NEXT: and x0, x8, #0xff 350; CHECK-NEXT: ret 351; 352; CHECKBE-LABEL: multiple_load_or: 353; CHECKBE: // %bb.0: 354; CHECKBE-NEXT: ldrh w8, [x0] 355; CHECKBE-NEXT: ldr w9, [x1] 356; CHECKBE-NEXT: orr w8, w9, w8 357; CHECKBE-NEXT: and x0, x8, #0xff 358; CHECKBE-NEXT: ret 359 %x = load i16, ptr %p, align 4 360 %xz = zext i16 %x to i64 361 %y = load i32, ptr %q, align 4 362 %yz = zext i32 %y to i64 363 %a = or i64 %yz, %xz 364 %r = and i64 %a, 255 365 ret i64 %r 366} 367 368define i64 @load32_and16_zexty(ptr %p, i32 %y) { 369; CHECK-LABEL: load32_and16_zexty: 370; CHECK: // %bb.0: 371; CHECK-NEXT: ldr w8, [x0] 372; CHECK-NEXT: orr w8, w1, w8 373; CHECK-NEXT: and x0, x8, #0xffff 374; CHECK-NEXT: ret 375; 376; CHECKBE-LABEL: load32_and16_zexty: 377; CHECKBE: // %bb.0: 378; CHECKBE-NEXT: ldr w8, [x0] 379; CHECKBE-NEXT: orr w8, w1, w8 380; CHECKBE-NEXT: and x0, x8, #0xffff 381; CHECKBE-NEXT: ret 382 %x = load i32, ptr %p, align 4 383 %xz = zext i32 %x to i64 384 %yz = zext i32 %y to i64 385 %a = or i64 %yz, %xz 386 %r = and i64 %a, 65535 387 ret i64 %r 388} 389 390define i64 @load32_and16_sexty(ptr %p, i32 %y) { 391; CHECK-LABEL: load32_and16_sexty: 392; CHECK: // %bb.0: 393; CHECK-NEXT: ldr w8, [x0] 394; CHECK-NEXT: orr w8, w1, w8 395; CHECK-NEXT: and x0, x8, #0xffff 396; CHECK-NEXT: ret 397; 398; CHECKBE-LABEL: load32_and16_sexty: 399; CHECKBE: // %bb.0: 400; CHECKBE-NEXT: ldr w8, [x0] 401; CHECKBE-NEXT: orr w8, w1, w8 402; CHECKBE-NEXT: and x0, x8, #0xffff 403; CHECKBE-NEXT: ret 404 %x = load i32, ptr %p, align 4 405 %xz = zext i32 %x to i64 406 %yz = sext i32 %y to i64 407 %a = or i64 %yz, %xz 408 %r = and i64 %a, 65535 409 ret i64 %r 410} 411 412define zeroext i1 @bigger(ptr nocapture readonly %c, ptr nocapture readonly %e, i64 %d, i64 %p1) { 413; CHECK-LABEL: bigger: 414; CHECK: // %bb.0: // %entry 415; CHECK-NEXT: ldrb w8, [x1, x2] 416; CHECK-NEXT: ldrb w9, [x0, x2] 417; CHECK-NEXT: and w10, w3, #0x7 418; CHECK-NEXT: mov w11, #8 // =0x8 419; CHECK-NEXT: sub w10, w11, w10 420; CHECK-NEXT: eor w8, w8, w9 421; CHECK-NEXT: mov w9, #5 // =0x5 422; CHECK-NEXT: lsr w8, w8, w10 423; CHECK-NEXT: tst w8, w9 424; CHECK-NEXT: cset w0, eq 425; CHECK-NEXT: ret 426; 427; CHECKBE-LABEL: bigger: 428; CHECKBE: // %bb.0: // %entry 429; CHECKBE-NEXT: ldrb w8, [x1, x2] 430; CHECKBE-NEXT: ldrb w9, [x0, x2] 431; CHECKBE-NEXT: and w10, w3, #0x7 432; CHECKBE-NEXT: mov w11, #8 // =0x8 433; CHECKBE-NEXT: sub w10, w11, w10 434; CHECKBE-NEXT: eor w8, w8, w9 435; CHECKBE-NEXT: mov w9, #5 // =0x5 436; CHECKBE-NEXT: lsr w8, w8, w10 437; CHECKBE-NEXT: tst w8, w9 438; CHECKBE-NEXT: cset w0, eq 439; CHECKBE-NEXT: ret 440entry: 441 %0 = trunc i64 %p1 to i16 442 %1 = and i16 %0, 7 443 %sh_prom = sub nuw nsw i16 8, %1 444 %shl = shl nuw nsw i16 5, %sh_prom 445 %arrayidx = getelementptr inbounds i8, ptr %c, i64 %d 446 %2 = load i8, ptr %arrayidx, align 1 447 %3 = and i16 %shl, 255 448 %conv2 = zext i16 %3 to i32 449 %arrayidx3 = getelementptr inbounds i8, ptr %e, i64 %d 450 %4 = load i8, ptr %arrayidx3, align 1 451 %5 = xor i8 %4, %2 452 %6 = zext i8 %5 to i32 453 %7 = and i32 %6, %conv2 454 %cmp.not = icmp eq i32 %7, 0 455 ret i1 %cmp.not 456} 457