1; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort=1 -aarch64-atomic-cfg-tidy=false -disable-cgp-branch-opts -verify-machineinstrs < %s | FileCheck %s 2 3; 4; Test folding of the sign-/zero-extend into the load instruction. 5; 6 7; Unscaled 8define i32 @load_unscaled_zext_i8_to_i32(i64 %a) { 9; CHECK-LABEL: load_unscaled_zext_i8_to_i32 10; CHECK: ldurb w0, [x0, #-8] 11; CHECK-NOT: uxtb 12 %1 = sub i64 %a, 8 13 %2 = inttoptr i64 %1 to i8* 14 %3 = load i8, i8* %2 15 br label %bb2 16 17bb2: 18 %4 = zext i8 %3 to i32 19 ret i32 %4 20} 21 22define i32 @load_unscaled_zext_i16_to_i32(i64 %a) { 23; CHECK-LABEL: load_unscaled_zext_i16_to_i32 24; CHECK: ldurh w0, [x0, #-8] 25; CHECK-NOT: uxth 26 %1 = sub i64 %a, 8 27 %2 = inttoptr i64 %1 to i16* 28 %3 = load i16, i16* %2 29 br label %bb2 30 31bb2: 32 %4 = zext i16 %3 to i32 33 ret i32 %4 34} 35 36define i64 @load_unscaled_zext_i8_to_i64(i64 %a) { 37; CHECK-LABEL: load_unscaled_zext_i8_to_i64 38; CHECK: ldurb w0, [x0, #-8] 39; CHECK-NOT: uxtb 40 %1 = sub i64 %a, 8 41 %2 = inttoptr i64 %1 to i8* 42 %3 = load i8, i8* %2 43 br label %bb2 44 45bb2: 46 %4 = zext i8 %3 to i64 47 ret i64 %4 48} 49 50define i64 @load_unscaled_zext_i16_to_i64(i64 %a) { 51; CHECK-LABEL: load_unscaled_zext_i16_to_i64 52; CHECK: ldurh w0, [x0, #-8] 53; CHECK-NOT: uxth 54 %1 = sub i64 %a, 8 55 %2 = inttoptr i64 %1 to i16* 56 %3 = load i16, i16* %2 57 br label %bb2 58 59bb2: 60 %4 = zext i16 %3 to i64 61 ret i64 %4 62} 63 64define i64 @load_unscaled_zext_i32_to_i64(i64 %a) { 65; CHECK-LABEL: load_unscaled_zext_i32_to_i64 66; CHECK: ldur w0, [x0, #-8] 67; CHECK-NOT: uxtw 68 %1 = sub i64 %a, 8 69 %2 = inttoptr i64 %1 to i32* 70 %3 = load i32, i32* %2 71 br label %bb2 72 73bb2: 74 %4 = zext i32 %3 to i64 75 ret i64 %4 76} 77 78define i32 @load_unscaled_sext_i8_to_i32(i64 %a) { 79; CHECK-LABEL: load_unscaled_sext_i8_to_i32 80; CHECK: ldursb w0, [x0, #-8] 81; CHECK-NOT: sxtb 82 %1 = sub i64 %a, 8 83 %2 = inttoptr i64 %1 to i8* 84 %3 = load i8, i8* %2 85 br label %bb2 86 87bb2: 88 %4 = sext i8 %3 to i32 89 ret i32 %4 90} 91 92define i32 @load_unscaled_sext_i16_to_i32(i64 %a) { 93; CHECK-LABEL: load_unscaled_sext_i16_to_i32 94; CHECK: ldursh w0, [x0, #-8] 95; CHECK-NOT: sxth 96 %1 = sub i64 %a, 8 97 %2 = inttoptr i64 %1 to i16* 98 %3 = load i16, i16* %2 99 br label %bb2 100 101bb2: 102 %4 = sext i16 %3 to i32 103 ret i32 %4 104} 105 106define i64 @load_unscaled_sext_i8_to_i64(i64 %a) { 107; CHECK-LABEL: load_unscaled_sext_i8_to_i64 108; CHECK: ldursb x0, [x0, #-8] 109; CHECK-NOT: sxtb 110 %1 = sub i64 %a, 8 111 %2 = inttoptr i64 %1 to i8* 112 %3 = load i8, i8* %2 113 br label %bb2 114 115bb2: 116 %4 = sext i8 %3 to i64 117 ret i64 %4 118} 119 120define i64 @load_unscaled_sext_i16_to_i64(i64 %a) { 121; CHECK-LABEL: load_unscaled_sext_i16_to_i64 122; CHECK: ldursh x0, [x0, #-8] 123; CHECK-NOT: sxth 124 %1 = sub i64 %a, 8 125 %2 = inttoptr i64 %1 to i16* 126 %3 = load i16, i16* %2 127 br label %bb2 128 129bb2: 130 %4 = sext i16 %3 to i64 131 ret i64 %4 132} 133 134define i64 @load_unscaled_sext_i32_to_i64(i64 %a) { 135; CHECK-LABEL: load_unscaled_sext_i32_to_i64 136; CHECK: ldursw x0, [x0, #-8] 137; CHECK-NOT: sxtw 138 %1 = sub i64 %a, 8 139 %2 = inttoptr i64 %1 to i32* 140 %3 = load i32, i32* %2 141 br label %bb2 142 143bb2: 144 %4 = sext i32 %3 to i64 145 ret i64 %4 146} 147 148; Register 149define i32 @load_register_zext_i8_to_i32(i64 %a, i64 %b) { 150; CHECK-LABEL: load_register_zext_i8_to_i32 151; CHECK: ldrb w0, [x0, x1] 152; CHECK-NOT: uxtb 153 %1 = add i64 %a, %b 154 %2 = inttoptr i64 %1 to i8* 155 %3 = load i8, i8* %2 156 br label %bb2 157 158bb2: 159 %4 = zext i8 %3 to i32 160 ret i32 %4 161} 162 163define i32 @load_register_zext_i16_to_i32(i64 %a, i64 %b) { 164; CHECK-LABEL: load_register_zext_i16_to_i32 165; CHECK: ldrh w0, [x0, x1] 166; CHECK-NOT: uxth 167 %1 = add i64 %a, %b 168 %2 = inttoptr i64 %1 to i16* 169 %3 = load i16, i16* %2 170 br label %bb2 171 172bb2: 173 %4 = zext i16 %3 to i32 174 ret i32 %4 175} 176 177define i64 @load_register_zext_i8_to_i64(i64 %a, i64 %b) { 178; CHECK-LABEL: load_register_zext_i8_to_i64 179; CHECK: ldrb w0, [x0, x1] 180; CHECK-NOT: uxtb 181 %1 = add i64 %a, %b 182 %2 = inttoptr i64 %1 to i8* 183 %3 = load i8, i8* %2 184 br label %bb2 185 186bb2: 187 %4 = zext i8 %3 to i64 188 ret i64 %4 189} 190 191define i64 @load_register_zext_i16_to_i64(i64 %a, i64 %b) { 192; CHECK-LABEL: load_register_zext_i16_to_i64 193; CHECK: ldrh w0, [x0, x1] 194; CHECK-NOT: uxth 195 %1 = add i64 %a, %b 196 %2 = inttoptr i64 %1 to i16* 197 %3 = load i16, i16* %2 198 br label %bb2 199 200bb2: 201 %4 = zext i16 %3 to i64 202 ret i64 %4 203} 204 205define i64 @load_register_zext_i32_to_i64(i64 %a, i64 %b) { 206; CHECK-LABEL: load_register_zext_i32_to_i64 207; CHECK: ldr w0, [x0, x1] 208; CHECK-NOT: uxtw 209 %1 = add i64 %a, %b 210 %2 = inttoptr i64 %1 to i32* 211 %3 = load i32, i32* %2 212 br label %bb2 213 214bb2: 215 %4 = zext i32 %3 to i64 216 ret i64 %4 217} 218 219define i32 @load_register_sext_i8_to_i32(i64 %a, i64 %b) { 220; CHECK-LABEL: load_register_sext_i8_to_i32 221; CHECK: ldrsb w0, [x0, x1] 222; CHECK-NOT: sxtb 223 %1 = add i64 %a, %b 224 %2 = inttoptr i64 %1 to i8* 225 %3 = load i8, i8* %2 226 br label %bb2 227 228bb2: 229 %4 = sext i8 %3 to i32 230 ret i32 %4 231} 232 233define i32 @load_register_sext_i16_to_i32(i64 %a, i64 %b) { 234; CHECK-LABEL: load_register_sext_i16_to_i32 235; CHECK: ldrsh w0, [x0, x1] 236; CHECK-NOT: sxth 237 %1 = add i64 %a, %b 238 %2 = inttoptr i64 %1 to i16* 239 %3 = load i16, i16* %2 240 br label %bb2 241 242bb2: 243 %4 = sext i16 %3 to i32 244 ret i32 %4 245} 246 247define i64 @load_register_sext_i8_to_i64(i64 %a, i64 %b) { 248; CHECK-LABEL: load_register_sext_i8_to_i64 249; CHECK: ldrsb x0, [x0, x1] 250; CHECK-NOT: sxtb 251 %1 = add i64 %a, %b 252 %2 = inttoptr i64 %1 to i8* 253 %3 = load i8, i8* %2 254 br label %bb2 255 256bb2: 257 %4 = sext i8 %3 to i64 258 ret i64 %4 259} 260 261define i64 @load_register_sext_i16_to_i64(i64 %a, i64 %b) { 262; CHECK-LABEL: load_register_sext_i16_to_i64 263; CHECK: ldrsh x0, [x0, x1] 264; CHECK-NOT: sxth 265 %1 = add i64 %a, %b 266 %2 = inttoptr i64 %1 to i16* 267 %3 = load i16, i16* %2 268 br label %bb2 269 270bb2: 271 %4 = sext i16 %3 to i64 272 ret i64 %4 273} 274 275define i64 @load_register_sext_i32_to_i64(i64 %a, i64 %b) { 276; CHECK-LABEL: load_register_sext_i32_to_i64 277; CHECK: ldrsw x0, [x0, x1] 278; CHECK-NOT: sxtw 279 %1 = add i64 %a, %b 280 %2 = inttoptr i64 %1 to i32* 281 %3 = load i32, i32* %2 282 br label %bb2 283 284bb2: 285 %4 = sext i32 %3 to i64 286 ret i64 %4 287} 288 289; Extend 290define i32 @load_extend_zext_i8_to_i32(i64 %a, i32 %b) { 291; CHECK-LABEL: load_extend_zext_i8_to_i32 292; CHECK: ldrb w0, [x0, w1, sxtw] 293; CHECK-NOT: uxtb 294 %1 = sext i32 %b to i64 295 %2 = add i64 %a, %1 296 %3 = inttoptr i64 %2 to i8* 297 %4 = load i8, i8* %3 298 br label %bb2 299 300bb2: 301 %5 = zext i8 %4 to i32 302 ret i32 %5 303} 304 305define i32 @load_extend_zext_i16_to_i32(i64 %a, i32 %b) { 306; CHECK-LABEL: load_extend_zext_i16_to_i32 307; CHECK: ldrh w0, [x0, w1, sxtw] 308; CHECK-NOT: uxth 309 %1 = sext i32 %b to i64 310 %2 = add i64 %a, %1 311 %3 = inttoptr i64 %2 to i16* 312 %4 = load i16, i16* %3 313 br label %bb2 314 315bb2: 316 %5 = zext i16 %4 to i32 317 ret i32 %5 318} 319 320define i64 @load_extend_zext_i8_to_i64(i64 %a, i32 %b) { 321; CHECK-LABEL: load_extend_zext_i8_to_i64 322; CHECK: ldrb w0, [x0, w1, sxtw] 323; CHECK-NOT: uxtb 324 %1 = sext i32 %b to i64 325 %2 = add i64 %a, %1 326 %3 = inttoptr i64 %2 to i8* 327 %4 = load i8, i8* %3 328 br label %bb2 329 330bb2: 331 %5 = zext i8 %4 to i64 332 ret i64 %5 333} 334 335define i64 @load_extend_zext_i16_to_i64(i64 %a, i32 %b) { 336; CHECK-LABEL: load_extend_zext_i16_to_i64 337; CHECK: ldrh w0, [x0, w1, sxtw] 338; CHECK-NOT: uxth 339 %1 = sext i32 %b to i64 340 %2 = add i64 %a, %1 341 %3 = inttoptr i64 %2 to i16* 342 %4 = load i16, i16* %3 343 br label %bb2 344 345bb2: 346 %5 = zext i16 %4 to i64 347 ret i64 %5 348} 349 350define i64 @load_extend_zext_i32_to_i64(i64 %a, i32 %b) { 351; CHECK-LABEL: load_extend_zext_i32_to_i64 352; CHECK: ldr w0, [x0, w1, sxtw] 353; CHECK-NOT: uxtw 354 %1 = sext i32 %b to i64 355 %2 = add i64 %a, %1 356 %3 = inttoptr i64 %2 to i32* 357 %4 = load i32, i32* %3 358 br label %bb2 359 360bb2: 361 %5 = zext i32 %4 to i64 362 ret i64 %5 363} 364 365define i32 @load_extend_sext_i8_to_i32(i64 %a, i32 %b) { 366; CHECK-LABEL: load_extend_sext_i8_to_i32 367; CHECK: ldrsb w0, [x0, w1, sxtw] 368; CHECK-NOT: sxtb 369 %1 = sext i32 %b to i64 370 %2 = add i64 %a, %1 371 %3 = inttoptr i64 %2 to i8* 372 %4 = load i8, i8* %3 373 br label %bb2 374 375bb2: 376 %5 = sext i8 %4 to i32 377 ret i32 %5 378} 379 380define i32 @load_extend_sext_i16_to_i32(i64 %a, i32 %b) { 381; CHECK-LABEL: load_extend_sext_i16_to_i32 382; CHECK: ldrsh w0, [x0, w1, sxtw] 383; CHECK-NOT: sxth 384 %1 = sext i32 %b to i64 385 %2 = add i64 %a, %1 386 %3 = inttoptr i64 %2 to i16* 387 %4 = load i16, i16* %3 388 br label %bb2 389 390bb2: 391 %5 = sext i16 %4 to i32 392 ret i32 %5 393} 394 395define i64 @load_extend_sext_i8_to_i64(i64 %a, i32 %b) { 396; CHECK-LABEL: load_extend_sext_i8_to_i64 397; CHECK: ldrsb x0, [x0, w1, sxtw] 398; CHECK-NOT: sxtb 399 %1 = sext i32 %b to i64 400 %2 = add i64 %a, %1 401 %3 = inttoptr i64 %2 to i8* 402 %4 = load i8, i8* %3 403 br label %bb2 404 405bb2: 406 %5 = sext i8 %4 to i64 407 ret i64 %5 408} 409 410define i64 @load_extend_sext_i16_to_i64(i64 %a, i32 %b) { 411; CHECK-LABEL: load_extend_sext_i16_to_i64 412; CHECK: ldrsh x0, [x0, w1, sxtw] 413; CHECK-NOT: sxth 414 %1 = sext i32 %b to i64 415 %2 = add i64 %a, %1 416 %3 = inttoptr i64 %2 to i16* 417 %4 = load i16, i16* %3 418 br label %bb2 419 420bb2: 421 %5 = sext i16 %4 to i64 422 ret i64 %5 423} 424 425define i64 @load_extend_sext_i32_to_i64(i64 %a, i32 %b) { 426; CHECK-LABEL: load_extend_sext_i32_to_i64 427; CHECK: ldrsw x0, [x0, w1, sxtw] 428; CHECK-NOT: sxtw 429 %1 = sext i32 %b to i64 430 %2 = add i64 %a, %1 431 %3 = inttoptr i64 %2 to i32* 432 %4 = load i32, i32* %3 433 br label %bb2 434 435bb2: 436 %5 = sext i32 %4 to i64 437 ret i64 %5 438} 439 440