1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s --check-prefixes=CHECK,LE 3; RUN: llc < %s -mtriple=aarch64_be-- | FileCheck %s --check-prefixes=CHECK,BE 4 5define void @le_i16_to_i8(i16 %x, i8* %p0) { 6; LE-LABEL: le_i16_to_i8: 7; LE: // %bb.0: 8; LE-NEXT: strh w0, [x1] 9; LE-NEXT: ret 10; 11; BE-LABEL: le_i16_to_i8: 12; BE: // %bb.0: 13; BE-NEXT: rev w8, w0 14; BE-NEXT: lsr w8, w8, #16 15; BE-NEXT: strh w8, [x1] 16; BE-NEXT: ret 17 %sh1 = lshr i16 %x, 8 18 %t0 = trunc i16 %x to i8 19 %t1 = trunc i16 %sh1 to i8 20 %p1 = getelementptr inbounds i8, i8* %p0, i64 1 21 store i8 %t0, i8* %p0, align 1 22 store i8 %t1, i8* %p1, align 1 23 ret void 24} 25 26define void @le_i16_to_i8_order(i16 %x, i8* %p0) { 27; LE-LABEL: le_i16_to_i8_order: 28; LE: // %bb.0: 29; LE-NEXT: strh w0, [x1] 30; LE-NEXT: ret 31; 32; BE-LABEL: le_i16_to_i8_order: 33; BE: // %bb.0: 34; BE-NEXT: rev w8, w0 35; BE-NEXT: lsr w8, w8, #16 36; BE-NEXT: strh w8, [x1] 37; BE-NEXT: ret 38 %sh1 = lshr i16 %x, 8 39 %t0 = trunc i16 %x to i8 40 %t1 = trunc i16 %sh1 to i8 41 %p1 = getelementptr inbounds i8, i8* %p0, i64 1 42 store i8 %t1, i8* %p1, align 1 43 store i8 %t0, i8* %p0, align 1 44 ret void 45} 46 47define void @be_i16_to_i8_offset(i16 %x, i8* %p0) { 48; LE-LABEL: be_i16_to_i8_offset: 49; LE: // %bb.0: 50; LE-NEXT: rev w8, w0 51; LE-NEXT: lsr w8, w8, #16 52; LE-NEXT: sturh w8, [x1, #11] 53; LE-NEXT: ret 54; 55; BE-LABEL: be_i16_to_i8_offset: 56; BE: // %bb.0: 57; BE-NEXT: sturh w0, [x1, #11] 58; BE-NEXT: ret 59 %sh1 = lshr i16 %x, 8 60 %t0 = trunc i16 %x to i8 61 %t1 = trunc i16 %sh1 to i8 62 %p11 = getelementptr inbounds i8, i8* %p0, i64 11 63 %p12 = getelementptr inbounds i8, i8* %p0, i64 12 64 store i8 %t0, i8* %p12, align 1 65 store i8 %t1, i8* %p11, align 1 66 ret void 67} 68 69define void @be_i16_to_i8_order(i16 %x, i8* %p0) { 70; LE-LABEL: be_i16_to_i8_order: 71; LE: // %bb.0: 72; LE-NEXT: rev w8, w0 73; LE-NEXT: lsr w8, w8, #16 74; LE-NEXT: strh w8, [x1] 75; LE-NEXT: ret 76; 77; BE-LABEL: be_i16_to_i8_order: 78; BE: // %bb.0: 79; BE-NEXT: strh w0, [x1] 80; BE-NEXT: ret 81 %sh1 = lshr i16 %x, 8 82 %t0 = trunc i16 %x to i8 83 %t1 = trunc i16 %sh1 to i8 84 %p1 = getelementptr inbounds i8, i8* %p0, i64 1 85 store i8 %t1, i8* %p0, align 1 86 store i8 %t0, i8* %p1, align 1 87 ret void 88} 89 90define void @le_i32_to_i8(i32 %x, i8* %p0) { 91; LE-LABEL: le_i32_to_i8: 92; LE: // %bb.0: 93; LE-NEXT: str w0, [x1] 94; LE-NEXT: ret 95; 96; BE-LABEL: le_i32_to_i8: 97; BE: // %bb.0: 98; BE-NEXT: rev w8, w0 99; BE-NEXT: str w8, [x1] 100; BE-NEXT: ret 101 %sh1 = lshr i32 %x, 8 102 %sh2 = lshr i32 %x, 16 103 %sh3 = lshr i32 %x, 24 104 %t0 = trunc i32 %x to i8 105 %t1 = trunc i32 %sh1 to i8 106 %t2 = trunc i32 %sh2 to i8 107 %t3 = trunc i32 %sh3 to i8 108 %p1 = getelementptr inbounds i8, i8* %p0, i64 1 109 %p2 = getelementptr inbounds i8, i8* %p0, i64 2 110 %p3 = getelementptr inbounds i8, i8* %p0, i64 3 111 store i8 %t0, i8* %p0, align 1 112 store i8 %t1, i8* %p1, align 1 113 store i8 %t2, i8* %p2, align 1 114 store i8 %t3, i8* %p3, align 1 115 ret void 116} 117 118define void @le_i32_to_i8_order(i32 %x, i8* %p0) { 119; LE-LABEL: le_i32_to_i8_order: 120; LE: // %bb.0: 121; LE-NEXT: str w0, [x1] 122; LE-NEXT: ret 123; 124; BE-LABEL: le_i32_to_i8_order: 125; BE: // %bb.0: 126; BE-NEXT: rev w8, w0 127; BE-NEXT: str w8, [x1] 128; BE-NEXT: ret 129 %sh1 = lshr i32 %x, 8 130 %sh2 = lshr i32 %x, 16 131 %sh3 = lshr i32 %x, 24 132 %t0 = trunc i32 %x to i8 133 %t1 = trunc i32 %sh1 to i8 134 %t2 = trunc i32 %sh2 to i8 135 %t3 = trunc i32 %sh3 to i8 136 %p1 = getelementptr inbounds i8, i8* %p0, i64 1 137 %p2 = getelementptr inbounds i8, i8* %p0, i64 2 138 %p3 = getelementptr inbounds i8, i8* %p0, i64 3 139 store i8 %t3, i8* %p3, align 1 140 store i8 %t1, i8* %p1, align 1 141 store i8 %t0, i8* %p0, align 1 142 store i8 %t2, i8* %p2, align 1 143 ret void 144} 145 146define void @be_i32_to_i8(i32 %x, i8* %p0) { 147; LE-LABEL: be_i32_to_i8: 148; LE: // %bb.0: 149; LE-NEXT: rev w8, w0 150; LE-NEXT: str w8, [x1] 151; LE-NEXT: ret 152; 153; BE-LABEL: be_i32_to_i8: 154; BE: // %bb.0: 155; BE-NEXT: str w0, [x1] 156; BE-NEXT: ret 157 %sh1 = lshr i32 %x, 8 158 %sh2 = lshr i32 %x, 16 159 %sh3 = lshr i32 %x, 24 160 %t0 = trunc i32 %x to i8 161 %t1 = trunc i32 %sh1 to i8 162 %t2 = trunc i32 %sh2 to i8 163 %t3 = trunc i32 %sh3 to i8 164 %p1 = getelementptr inbounds i8, i8* %p0, i64 1 165 %p2 = getelementptr inbounds i8, i8* %p0, i64 2 166 %p3 = getelementptr inbounds i8, i8* %p0, i64 3 167 store i8 %t0, i8* %p3, align 1 168 store i8 %t1, i8* %p2, align 1 169 store i8 %t2, i8* %p1, align 1 170 store i8 %t3, i8* %p0, align 1 171 ret void 172} 173 174define void @be_i32_to_i8_order(i32 %x, i8* %p0) { 175; LE-LABEL: be_i32_to_i8_order: 176; LE: // %bb.0: 177; LE-NEXT: rev w8, w0 178; LE-NEXT: str w8, [x1] 179; LE-NEXT: ret 180; 181; BE-LABEL: be_i32_to_i8_order: 182; BE: // %bb.0: 183; BE-NEXT: str w0, [x1] 184; BE-NEXT: ret 185 %sh1 = lshr i32 %x, 8 186 %sh2 = lshr i32 %x, 16 187 %sh3 = lshr i32 %x, 24 188 %t0 = trunc i32 %x to i8 189 %t1 = trunc i32 %sh1 to i8 190 %t2 = trunc i32 %sh2 to i8 191 %t3 = trunc i32 %sh3 to i8 192 %p1 = getelementptr inbounds i8, i8* %p0, i64 1 193 %p2 = getelementptr inbounds i8, i8* %p0, i64 2 194 %p3 = getelementptr inbounds i8, i8* %p0, i64 3 195 store i8 %t3, i8* %p0, align 1 196 store i8 %t2, i8* %p1, align 1 197 store i8 %t0, i8* %p3, align 1 198 store i8 %t1, i8* %p2, align 1 199 ret void 200} 201 202define void @le_i32_to_i16(i32 %x, i16* %p0) { 203; LE-LABEL: le_i32_to_i16: 204; LE: // %bb.0: 205; LE-NEXT: str w0, [x1] 206; LE-NEXT: ret 207; 208; BE-LABEL: le_i32_to_i16: 209; BE: // %bb.0: 210; BE-NEXT: ror w8, w0, #16 211; BE-NEXT: str w8, [x1] 212; BE-NEXT: ret 213 %sh1 = lshr i32 %x, 16 214 %t0 = trunc i32 %x to i16 215 %t1 = trunc i32 %sh1 to i16 216 %p1 = getelementptr inbounds i16, i16* %p0, i64 1 217 store i16 %t0, i16* %p0, align 2 218 store i16 %t1, i16* %p1, align 2 219 ret void 220} 221 222define void @le_i32_to_i16_order(i32 %x, i16* %p0) { 223; LE-LABEL: le_i32_to_i16_order: 224; LE: // %bb.0: 225; LE-NEXT: str w0, [x1] 226; LE-NEXT: ret 227; 228; BE-LABEL: le_i32_to_i16_order: 229; BE: // %bb.0: 230; BE-NEXT: ror w8, w0, #16 231; BE-NEXT: str w8, [x1] 232; BE-NEXT: ret 233 %sh1 = lshr i32 %x, 16 234 %t0 = trunc i32 %x to i16 235 %t1 = trunc i32 %sh1 to i16 236 %p1 = getelementptr inbounds i16, i16* %p0, i64 1 237 store i16 %t1, i16* %p1, align 2 238 store i16 %t0, i16* %p0, align 2 239 ret void 240} 241 242define void @be_i32_to_i16(i32 %x, i16* %p0) { 243; LE-LABEL: be_i32_to_i16: 244; LE: // %bb.0: 245; LE-NEXT: ror w8, w0, #16 246; LE-NEXT: str w8, [x1] 247; LE-NEXT: ret 248; 249; BE-LABEL: be_i32_to_i16: 250; BE: // %bb.0: 251; BE-NEXT: str w0, [x1] 252; BE-NEXT: ret 253 %sh1 = lshr i32 %x, 16 254 %t0 = trunc i32 %x to i16 255 %t1 = trunc i32 %sh1 to i16 256 %p1 = getelementptr inbounds i16, i16* %p0, i64 1 257 store i16 %t0, i16* %p1, align 2 258 store i16 %t1, i16* %p0, align 2 259 ret void 260} 261 262define void @be_i32_to_i16_order(i32 %x, i16* %p0) { 263; LE-LABEL: be_i32_to_i16_order: 264; LE: // %bb.0: 265; LE-NEXT: ror w8, w0, #16 266; LE-NEXT: str w8, [x1] 267; LE-NEXT: ret 268; 269; BE-LABEL: be_i32_to_i16_order: 270; BE: // %bb.0: 271; BE-NEXT: str w0, [x1] 272; BE-NEXT: ret 273 %sh1 = lshr i32 %x, 16 274 %t0 = trunc i32 %x to i16 275 %t1 = trunc i32 %sh1 to i16 276 %p1 = getelementptr inbounds i16, i16* %p0, i64 1 277 store i16 %t1, i16* %p0, align 2 278 store i16 %t0, i16* %p1, align 2 279 ret void 280} 281 282define void @le_i64_to_i8(i64 %x, i8* %p0) { 283; LE-LABEL: le_i64_to_i8: 284; LE: // %bb.0: 285; LE-NEXT: str x0, [x1] 286; LE-NEXT: ret 287; 288; BE-LABEL: le_i64_to_i8: 289; BE: // %bb.0: 290; BE-NEXT: rev x8, x0 291; BE-NEXT: str x8, [x1] 292; BE-NEXT: ret 293 %sh1 = lshr i64 %x, 8 294 %sh2 = lshr i64 %x, 16 295 %sh3 = lshr i64 %x, 24 296 %sh4 = lshr i64 %x, 32 297 %sh5 = lshr i64 %x, 40 298 %sh6 = lshr i64 %x, 48 299 %sh7 = lshr i64 %x, 56 300 %t0 = trunc i64 %x to i8 301 %t1 = trunc i64 %sh1 to i8 302 %t2 = trunc i64 %sh2 to i8 303 %t3 = trunc i64 %sh3 to i8 304 %t4 = trunc i64 %sh4 to i8 305 %t5 = trunc i64 %sh5 to i8 306 %t6 = trunc i64 %sh6 to i8 307 %t7 = trunc i64 %sh7 to i8 308 %p1 = getelementptr inbounds i8, i8* %p0, i64 1 309 %p2 = getelementptr inbounds i8, i8* %p0, i64 2 310 %p3 = getelementptr inbounds i8, i8* %p0, i64 3 311 %p4 = getelementptr inbounds i8, i8* %p0, i64 4 312 %p5 = getelementptr inbounds i8, i8* %p0, i64 5 313 %p6 = getelementptr inbounds i8, i8* %p0, i64 6 314 %p7 = getelementptr inbounds i8, i8* %p0, i64 7 315 store i8 %t0, i8* %p0, align 1 316 store i8 %t1, i8* %p1, align 1 317 store i8 %t2, i8* %p2, align 1 318 store i8 %t3, i8* %p3, align 1 319 store i8 %t4, i8* %p4, align 1 320 store i8 %t5, i8* %p5, align 1 321 store i8 %t6, i8* %p6, align 1 322 store i8 %t7, i8* %p7, align 1 323 ret void 324} 325 326define void @le_i64_to_i8_order(i64 %x, i8* %p0) { 327; LE-LABEL: le_i64_to_i8_order: 328; LE: // %bb.0: 329; LE-NEXT: str x0, [x1] 330; LE-NEXT: ret 331; 332; BE-LABEL: le_i64_to_i8_order: 333; BE: // %bb.0: 334; BE-NEXT: rev x8, x0 335; BE-NEXT: str x8, [x1] 336; BE-NEXT: ret 337 %sh1 = lshr i64 %x, 8 338 %sh2 = lshr i64 %x, 16 339 %sh3 = lshr i64 %x, 24 340 %sh4 = lshr i64 %x, 32 341 %sh5 = lshr i64 %x, 40 342 %sh6 = lshr i64 %x, 48 343 %sh7 = lshr i64 %x, 56 344 %t0 = trunc i64 %x to i8 345 %t1 = trunc i64 %sh1 to i8 346 %t2 = trunc i64 %sh2 to i8 347 %t3 = trunc i64 %sh3 to i8 348 %t4 = trunc i64 %sh4 to i8 349 %t5 = trunc i64 %sh5 to i8 350 %t6 = trunc i64 %sh6 to i8 351 %t7 = trunc i64 %sh7 to i8 352 %p1 = getelementptr inbounds i8, i8* %p0, i64 1 353 %p2 = getelementptr inbounds i8, i8* %p0, i64 2 354 %p3 = getelementptr inbounds i8, i8* %p0, i64 3 355 %p4 = getelementptr inbounds i8, i8* %p0, i64 4 356 %p5 = getelementptr inbounds i8, i8* %p0, i64 5 357 %p6 = getelementptr inbounds i8, i8* %p0, i64 6 358 %p7 = getelementptr inbounds i8, i8* %p0, i64 7 359 store i8 %t5, i8* %p5, align 1 360 store i8 %t0, i8* %p0, align 1 361 store i8 %t3, i8* %p3, align 1 362 store i8 %t7, i8* %p7, align 1 363 store i8 %t1, i8* %p1, align 1 364 store i8 %t6, i8* %p6, align 1 365 store i8 %t2, i8* %p2, align 1 366 store i8 %t4, i8* %p4, align 1 367 ret void 368} 369 370define void @be_i64_to_i8(i64 %x, i8* %p0) { 371; LE-LABEL: be_i64_to_i8: 372; LE: // %bb.0: 373; LE-NEXT: rev x8, x0 374; LE-NEXT: str x8, [x1] 375; LE-NEXT: ret 376; 377; BE-LABEL: be_i64_to_i8: 378; BE: // %bb.0: 379; BE-NEXT: str x0, [x1] 380; BE-NEXT: ret 381 %sh1 = lshr i64 %x, 8 382 %sh2 = lshr i64 %x, 16 383 %sh3 = lshr i64 %x, 24 384 %sh4 = lshr i64 %x, 32 385 %sh5 = lshr i64 %x, 40 386 %sh6 = lshr i64 %x, 48 387 %sh7 = lshr i64 %x, 56 388 %t0 = trunc i64 %x to i8 389 %t1 = trunc i64 %sh1 to i8 390 %t2 = trunc i64 %sh2 to i8 391 %t3 = trunc i64 %sh3 to i8 392 %t4 = trunc i64 %sh4 to i8 393 %t5 = trunc i64 %sh5 to i8 394 %t6 = trunc i64 %sh6 to i8 395 %t7 = trunc i64 %sh7 to i8 396 %p1 = getelementptr inbounds i8, i8* %p0, i64 1 397 %p2 = getelementptr inbounds i8, i8* %p0, i64 2 398 %p3 = getelementptr inbounds i8, i8* %p0, i64 3 399 %p4 = getelementptr inbounds i8, i8* %p0, i64 4 400 %p5 = getelementptr inbounds i8, i8* %p0, i64 5 401 %p6 = getelementptr inbounds i8, i8* %p0, i64 6 402 %p7 = getelementptr inbounds i8, i8* %p0, i64 7 403 store i8 %t0, i8* %p7, align 1 404 store i8 %t1, i8* %p6, align 1 405 store i8 %t2, i8* %p5, align 1 406 store i8 %t3, i8* %p4, align 1 407 store i8 %t4, i8* %p3, align 1 408 store i8 %t5, i8* %p2, align 1 409 store i8 %t6, i8* %p1, align 1 410 store i8 %t7, i8* %p0, align 1 411 ret void 412} 413 414define void @be_i64_to_i8_order(i64 %x, i8* %p0) { 415; LE-LABEL: be_i64_to_i8_order: 416; LE: // %bb.0: 417; LE-NEXT: rev x8, x0 418; LE-NEXT: str x8, [x1] 419; LE-NEXT: ret 420; 421; BE-LABEL: be_i64_to_i8_order: 422; BE: // %bb.0: 423; BE-NEXT: str x0, [x1] 424; BE-NEXT: ret 425 %sh1 = lshr i64 %x, 8 426 %sh2 = lshr i64 %x, 16 427 %sh3 = lshr i64 %x, 24 428 %sh4 = lshr i64 %x, 32 429 %sh5 = lshr i64 %x, 40 430 %sh6 = lshr i64 %x, 48 431 %sh7 = lshr i64 %x, 56 432 %t0 = trunc i64 %x to i8 433 %t1 = trunc i64 %sh1 to i8 434 %t2 = trunc i64 %sh2 to i8 435 %t3 = trunc i64 %sh3 to i8 436 %t4 = trunc i64 %sh4 to i8 437 %t5 = trunc i64 %sh5 to i8 438 %t6 = trunc i64 %sh6 to i8 439 %t7 = trunc i64 %sh7 to i8 440 %p1 = getelementptr inbounds i8, i8* %p0, i64 1 441 %p2 = getelementptr inbounds i8, i8* %p0, i64 2 442 %p3 = getelementptr inbounds i8, i8* %p0, i64 3 443 %p4 = getelementptr inbounds i8, i8* %p0, i64 4 444 %p5 = getelementptr inbounds i8, i8* %p0, i64 5 445 %p6 = getelementptr inbounds i8, i8* %p0, i64 6 446 %p7 = getelementptr inbounds i8, i8* %p0, i64 7 447 store i8 %t7, i8* %p0, align 1 448 store i8 %t6, i8* %p1, align 1 449 store i8 %t5, i8* %p2, align 1 450 store i8 %t4, i8* %p3, align 1 451 store i8 %t3, i8* %p4, align 1 452 store i8 %t2, i8* %p5, align 1 453 store i8 %t1, i8* %p6, align 1 454 store i8 %t0, i8* %p7, align 1 455 ret void 456} 457 458define void @le_i64_to_i16(i64 %x, i16* %p0) { 459; LE-LABEL: le_i64_to_i16: 460; LE: // %bb.0: 461; LE-NEXT: str x0, [x1] 462; LE-NEXT: ret 463; 464; BE-LABEL: le_i64_to_i16: 465; BE: // %bb.0: 466; BE-NEXT: lsr x8, x0, #16 467; BE-NEXT: lsr x9, x0, #32 468; BE-NEXT: lsr x10, x0, #48 469; BE-NEXT: strh w0, [x1] 470; BE-NEXT: strh w8, [x1, #2] 471; BE-NEXT: strh w9, [x1, #4] 472; BE-NEXT: strh w10, [x1, #6] 473; BE-NEXT: ret 474 %sh1 = lshr i64 %x, 16 475 %sh2 = lshr i64 %x, 32 476 %sh3 = lshr i64 %x, 48 477 %t0 = trunc i64 %x to i16 478 %t1 = trunc i64 %sh1 to i16 479 %t2 = trunc i64 %sh2 to i16 480 %t3 = trunc i64 %sh3 to i16 481 %p1 = getelementptr inbounds i16, i16* %p0, i64 1 482 %p2 = getelementptr inbounds i16, i16* %p0, i64 2 483 %p3 = getelementptr inbounds i16, i16* %p0, i64 3 484 store i16 %t0, i16* %p0, align 2 485 store i16 %t1, i16* %p1, align 2 486 store i16 %t2, i16* %p2, align 2 487 store i16 %t3, i16* %p3, align 2 488 ret void 489} 490 491define void @le_i64_to_i16_order(i64 %x, i16* %p0) { 492; LE-LABEL: le_i64_to_i16_order: 493; LE: // %bb.0: 494; LE-NEXT: str x0, [x1] 495; LE-NEXT: ret 496; 497; BE-LABEL: le_i64_to_i16_order: 498; BE: // %bb.0: 499; BE-NEXT: lsr x8, x0, #16 500; BE-NEXT: lsr x9, x0, #32 501; BE-NEXT: lsr x10, x0, #48 502; BE-NEXT: strh w0, [x1] 503; BE-NEXT: strh w8, [x1, #2] 504; BE-NEXT: strh w10, [x1, #6] 505; BE-NEXT: strh w9, [x1, #4] 506; BE-NEXT: ret 507 %sh1 = lshr i64 %x, 16 508 %sh2 = lshr i64 %x, 32 509 %sh3 = lshr i64 %x, 48 510 %t0 = trunc i64 %x to i16 511 %t1 = trunc i64 %sh1 to i16 512 %t2 = trunc i64 %sh2 to i16 513 %t3 = trunc i64 %sh3 to i16 514 %p1 = getelementptr inbounds i16, i16* %p0, i64 1 515 %p2 = getelementptr inbounds i16, i16* %p0, i64 2 516 %p3 = getelementptr inbounds i16, i16* %p0, i64 3 517 store i16 %t1, i16* %p1, align 2 518 store i16 %t3, i16* %p3, align 2 519 store i16 %t0, i16* %p0, align 2 520 store i16 %t2, i16* %p2, align 2 521 ret void 522} 523 524define void @be_i64_to_i16(i64 %x, i16* %p0) { 525; LE-LABEL: be_i64_to_i16: 526; LE: // %bb.0: 527; LE-NEXT: lsr x8, x0, #32 528; LE-NEXT: lsr x9, x0, #48 529; LE-NEXT: ror w10, w0, #16 530; LE-NEXT: str w10, [x1, #4] 531; LE-NEXT: strh w8, [x1, #2] 532; LE-NEXT: strh w9, [x1] 533; LE-NEXT: ret 534; 535; BE-LABEL: be_i64_to_i16: 536; BE: // %bb.0: 537; BE-NEXT: str x0, [x1] 538; BE-NEXT: ret 539 %sh1 = lshr i64 %x, 16 540 %sh2 = lshr i64 %x, 32 541 %sh3 = lshr i64 %x, 48 542 %t0 = trunc i64 %x to i16 543 %t1 = trunc i64 %sh1 to i16 544 %t2 = trunc i64 %sh2 to i16 545 %t3 = trunc i64 %sh3 to i16 546 %p1 = getelementptr inbounds i16, i16* %p0, i64 1 547 %p2 = getelementptr inbounds i16, i16* %p0, i64 2 548 %p3 = getelementptr inbounds i16, i16* %p0, i64 3 549 store i16 %t0, i16* %p3, align 2 550 store i16 %t1, i16* %p2, align 2 551 store i16 %t2, i16* %p1, align 2 552 store i16 %t3, i16* %p0, align 2 553 ret void 554} 555 556define void @be_i64_to_i16_order(i64 %x, i16* %p0) { 557; LE-LABEL: be_i64_to_i16_order: 558; LE: // %bb.0: 559; LE-NEXT: lsr x8, x0, #16 560; LE-NEXT: lsr x9, x0, #32 561; LE-NEXT: lsr x10, x0, #48 562; LE-NEXT: strh w0, [x1, #6] 563; LE-NEXT: strh w10, [x1] 564; LE-NEXT: strh w9, [x1, #2] 565; LE-NEXT: strh w8, [x1, #4] 566; LE-NEXT: ret 567; 568; BE-LABEL: be_i64_to_i16_order: 569; BE: // %bb.0: 570; BE-NEXT: str x0, [x1] 571; BE-NEXT: ret 572 %sh1 = lshr i64 %x, 16 573 %sh2 = lshr i64 %x, 32 574 %sh3 = lshr i64 %x, 48 575 %t0 = trunc i64 %x to i16 576 %t1 = trunc i64 %sh1 to i16 577 %t2 = trunc i64 %sh2 to i16 578 %t3 = trunc i64 %sh3 to i16 579 %p1 = getelementptr inbounds i16, i16* %p0, i64 1 580 %p2 = getelementptr inbounds i16, i16* %p0, i64 2 581 %p3 = getelementptr inbounds i16, i16* %p0, i64 3 582 store i16 %t0, i16* %p3, align 2 583 store i16 %t3, i16* %p0, align 2 584 store i16 %t2, i16* %p1, align 2 585 store i16 %t1, i16* %p2, align 2 586 ret void 587} 588 589define void @le_i64_to_i32(i64 %x, i32* %p0) { 590; LE-LABEL: le_i64_to_i32: 591; LE: // %bb.0: 592; LE-NEXT: str x0, [x1] 593; LE-NEXT: ret 594; 595; BE-LABEL: le_i64_to_i32: 596; BE: // %bb.0: 597; BE-NEXT: ror x8, x0, #32 598; BE-NEXT: str x8, [x1] 599; BE-NEXT: ret 600 %sh1 = lshr i64 %x, 32 601 %t0 = trunc i64 %x to i32 602 %t1 = trunc i64 %sh1 to i32 603 %p1 = getelementptr inbounds i32, i32* %p0, i64 1 604 store i32 %t0, i32* %p0, align 4 605 store i32 %t1, i32* %p1, align 4 606 ret void 607} 608 609define void @le_i64_to_i32_order(i64 %x, i32* %p0) { 610; LE-LABEL: le_i64_to_i32_order: 611; LE: // %bb.0: 612; LE-NEXT: str x0, [x1] 613; LE-NEXT: ret 614; 615; BE-LABEL: le_i64_to_i32_order: 616; BE: // %bb.0: 617; BE-NEXT: ror x8, x0, #32 618; BE-NEXT: str x8, [x1] 619; BE-NEXT: ret 620 %sh1 = lshr i64 %x, 32 621 %t0 = trunc i64 %x to i32 622 %t1 = trunc i64 %sh1 to i32 623 %p1 = getelementptr inbounds i32, i32* %p0, i64 1 624 store i32 %t1, i32* %p1, align 4 625 store i32 %t0, i32* %p0, align 4 626 ret void 627} 628 629define void @be_i64_to_i32(i64 %x, i32* %p0) { 630; LE-LABEL: be_i64_to_i32: 631; LE: // %bb.0: 632; LE-NEXT: ror x8, x0, #32 633; LE-NEXT: str x8, [x1] 634; LE-NEXT: ret 635; 636; BE-LABEL: be_i64_to_i32: 637; BE: // %bb.0: 638; BE-NEXT: str x0, [x1] 639; BE-NEXT: ret 640 %sh1 = lshr i64 %x, 32 641 %t0 = trunc i64 %x to i32 642 %t1 = trunc i64 %sh1 to i32 643 %p1 = getelementptr inbounds i32, i32* %p0, i64 1 644 store i32 %t0, i32* %p1, align 4 645 store i32 %t1, i32* %p0, align 4 646 ret void 647} 648 649define void @be_i64_to_i32_order(i64 %x, i32* %p0) { 650; LE-LABEL: be_i64_to_i32_order: 651; LE: // %bb.0: 652; LE-NEXT: ror x8, x0, #32 653; LE-NEXT: str x8, [x1] 654; LE-NEXT: ret 655; 656; BE-LABEL: be_i64_to_i32_order: 657; BE: // %bb.0: 658; BE-NEXT: str x0, [x1] 659; BE-NEXT: ret 660 %sh1 = lshr i64 %x, 32 661 %t0 = trunc i64 %x to i32 662 %t1 = trunc i64 %sh1 to i32 663 %p1 = getelementptr inbounds i32, i32* %p0, i64 1 664 store i32 %t1, i32* %p0, align 4 665 store i32 %t0, i32* %p1, align 4 666 ret void 667} 668 669; Negative test - not consecutive addresses 670 671define void @i64_to_i32_wrong_addr(i64 %x, i32* %p0) { 672; CHECK-LABEL: i64_to_i32_wrong_addr: 673; CHECK: // %bb.0: 674; CHECK-NEXT: lsr x8, x0, #32 675; CHECK-NEXT: str w8, [x1, #12] 676; CHECK-NEXT: str w0, [x1] 677; CHECK-NEXT: ret 678 %sh1 = lshr i64 %x, 32 679 %t0 = trunc i64 %x to i32 680 %t1 = trunc i64 %sh1 to i32 681 %p3 = getelementptr inbounds i32, i32* %p0, i64 3 682 store i32 %t1, i32* %p3, align 4 683 store i32 %t0, i32* %p0, align 4 684 ret void 685} 686 687; Negative test - addresses don't line up with shift amounts 688 689define void @i64_to_i16_wrong_order(i64 %x, i16* %p0) { 690; CHECK-LABEL: i64_to_i16_wrong_order: 691; CHECK: // %bb.0: 692; CHECK-NEXT: lsr x8, x0, #16 693; CHECK-NEXT: lsr x9, x0, #32 694; CHECK-NEXT: lsr x10, x0, #48 695; CHECK-NEXT: strh w10, [x1, #6] 696; CHECK-NEXT: strh w8, [x1, #4] 697; CHECK-NEXT: strh w9, [x1, #2] 698; CHECK-NEXT: strh w0, [x1] 699; CHECK-NEXT: ret 700 %sh1 = lshr i64 %x, 16 701 %sh2 = lshr i64 %x, 32 702 %sh3 = lshr i64 %x, 48 703 %t0 = trunc i64 %x to i16 704 %t1 = trunc i64 %sh1 to i16 705 %t2 = trunc i64 %sh2 to i16 706 %t3 = trunc i64 %sh3 to i16 707 %p1 = getelementptr inbounds i16, i16* %p0, i64 1 708 %p2 = getelementptr inbounds i16, i16* %p0, i64 2 709 %p3 = getelementptr inbounds i16, i16* %p0, i64 3 710 store i16 %t3, i16* %p3, align 2 711 store i16 %t1, i16* %p2, align 2 712 store i16 %t2, i16* %p1, align 2 713 store i16 %t0, i16* %p0, align 2 714 ret void 715} 716 717; Negative test - no store of 't1' 718 719define void @i32_to_i8_incomplete(i32 %x, i8* %p0) { 720; CHECK-LABEL: i32_to_i8_incomplete: 721; CHECK: // %bb.0: 722; CHECK-NEXT: lsr w8, w0, #16 723; CHECK-NEXT: lsr w9, w0, #24 724; CHECK-NEXT: strb w0, [x1] 725; CHECK-NEXT: strb w8, [x1, #2] 726; CHECK-NEXT: strb w9, [x1, #3] 727; CHECK-NEXT: ret 728 %sh1 = lshr i32 %x, 8 729 %sh2 = lshr i32 %x, 16 730 %sh3 = lshr i32 %x, 24 731 %t0 = trunc i32 %x to i8 732 %t1 = trunc i32 %sh1 to i8 733 %t2 = trunc i32 %sh2 to i8 734 %t3 = trunc i32 %sh3 to i8 735 %p1 = getelementptr inbounds i8, i8* %p0, i64 1 736 %p2 = getelementptr inbounds i8, i8* %p0, i64 2 737 %p3 = getelementptr inbounds i8, i8* %p0, i64 3 738 store i8 %t0, i8* %p0, align 1 739 store i8 %t2, i8* %p2, align 1 740 store i8 %t3, i8* %p3, align 1 741 ret void 742} 743 744; Negative test - no store of 't3' 745 746define void @i64_to_i8_incomplete(i64 %x, i8* %p0) { 747; CHECK-LABEL: i64_to_i8_incomplete: 748; CHECK: // %bb.0: 749; CHECK-NEXT: lsr x8, x0, #8 750; CHECK-NEXT: lsr x9, x0, #16 751; CHECK-NEXT: lsr x10, x0, #32 752; CHECK-NEXT: lsr x11, x0, #40 753; CHECK-NEXT: lsr x12, x0, #48 754; CHECK-NEXT: lsr x13, x0, #56 755; CHECK-NEXT: strb w13, [x1] 756; CHECK-NEXT: strb w12, [x1, #1] 757; CHECK-NEXT: strb w11, [x1, #2] 758; CHECK-NEXT: strb w10, [x1, #3] 759; CHECK-NEXT: strb w9, [x1, #5] 760; CHECK-NEXT: strb w8, [x1, #6] 761; CHECK-NEXT: strb w0, [x1, #7] 762; CHECK-NEXT: ret 763 %sh1 = lshr i64 %x, 8 764 %sh2 = lshr i64 %x, 16 765 %sh3 = lshr i64 %x, 24 766 %sh4 = lshr i64 %x, 32 767 %sh5 = lshr i64 %x, 40 768 %sh6 = lshr i64 %x, 48 769 %sh7 = lshr i64 %x, 56 770 %t0 = trunc i64 %x to i8 771 %t1 = trunc i64 %sh1 to i8 772 %t2 = trunc i64 %sh2 to i8 773 %t3 = trunc i64 %sh3 to i8 774 %t4 = trunc i64 %sh4 to i8 775 %t5 = trunc i64 %sh5 to i8 776 %t6 = trunc i64 %sh6 to i8 777 %t7 = trunc i64 %sh7 to i8 778 %p1 = getelementptr inbounds i8, i8* %p0, i64 1 779 %p2 = getelementptr inbounds i8, i8* %p0, i64 2 780 %p3 = getelementptr inbounds i8, i8* %p0, i64 3 781 %p4 = getelementptr inbounds i8, i8* %p0, i64 4 782 %p5 = getelementptr inbounds i8, i8* %p0, i64 5 783 %p6 = getelementptr inbounds i8, i8* %p0, i64 6 784 %p7 = getelementptr inbounds i8, i8* %p0, i64 7 785 store i8 %t7, i8* %p0, align 1 786 store i8 %t6, i8* %p1, align 1 787 store i8 %t5, i8* %p2, align 1 788 store i8 %t4, i8* %p3, align 1 789 store i8 %t2, i8* %p5, align 1 790 store i8 %t1, i8* %p6, align 1 791 store i8 %t0, i8* %p7, align 1 792 ret void 793} 794 795; Negative test - not consecutive addresses 796 797define void @i32_to_i16_wrong_addr(i32 %x, i16* %p0) { 798; CHECK-LABEL: i32_to_i16_wrong_addr: 799; CHECK: // %bb.0: 800; CHECK-NEXT: lsr w8, w0, #16 801; CHECK-NEXT: strh w8, [x1, #4] 802; CHECK-NEXT: strh w0, [x1] 803; CHECK-NEXT: ret 804 %sh1 = lshr i32 %x, 16 805 %t0 = trunc i32 %x to i16 806 %t1 = trunc i32 %sh1 to i16 807 %p2 = getelementptr inbounds i16, i16* %p0, i64 2 808 store i16 %t1, i16* %p2, align 2 809 store i16 %t0, i16* %p0, align 2 810 ret void 811} 812 813; Negative test - addresses don't line up with shift amounts 814 815define void @i32_to_i8_wrong_order(i32 %x, i8* %p0) { 816; CHECK-LABEL: i32_to_i8_wrong_order: 817; CHECK: // %bb.0: 818; CHECK-NEXT: lsr w8, w0, #8 819; CHECK-NEXT: lsr w9, w0, #16 820; CHECK-NEXT: lsr w10, w0, #24 821; CHECK-NEXT: strb w0, [x1, #3] 822; CHECK-NEXT: strb w10, [x1, #1] 823; CHECK-NEXT: strb w9, [x1] 824; CHECK-NEXT: strb w8, [x1, #2] 825; CHECK-NEXT: ret 826 %sh1 = lshr i32 %x, 8 827 %sh2 = lshr i32 %x, 16 828 %sh3 = lshr i32 %x, 24 829 %t0 = trunc i32 %x to i8 830 %t1 = trunc i32 %sh1 to i8 831 %t2 = trunc i32 %sh2 to i8 832 %t3 = trunc i32 %sh3 to i8 833 %p1 = getelementptr inbounds i8, i8* %p0, i64 1 834 %p2 = getelementptr inbounds i8, i8* %p0, i64 2 835 %p3 = getelementptr inbounds i8, i8* %p0, i64 3 836 store i8 %t3, i8* %p1, align 1 837 store i8 %t2, i8* %p0, align 1 838 store i8 %t0, i8* %p3, align 1 839 store i8 %t1, i8* %p2, align 1 840 ret void 841} 842