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 8 define 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 17 bb2: 18 %4 = zext i8 %3 to i32 19 ret i32 %4 20 } 21 22 define 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 31 bb2: 32 %4 = zext i16 %3 to i32 33 ret i32 %4 34 } 35 36 define 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 45 bb2: 46 %4 = zext i8 %3 to i64 47 ret i64 %4 48 } 49 50 define 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 59 bb2: 60 %4 = zext i16 %3 to i64 61 ret i64 %4 62 } 63 64 define 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 73 bb2: 74 %4 = zext i32 %3 to i64 75 ret i64 %4 76 } 77 78 define 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 87 bb2: 88 %4 = sext i8 %3 to i32 89 ret i32 %4 90 } 91 92 define 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 101 bb2: 102 %4 = sext i16 %3 to i32 103 ret i32 %4 104 } 105 106 define 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 115 bb2: 116 %4 = sext i8 %3 to i64 117 ret i64 %4 118 } 119 120 define 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 129 bb2: 130 %4 = sext i16 %3 to i64 131 ret i64 %4 132 } 133 134 define 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 143 bb2: 144 %4 = sext i32 %3 to i64 145 ret i64 %4 146 } 147 148 ; Register 149 define 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 158 bb2: 159 %4 = zext i8 %3 to i32 160 ret i32 %4 161 } 162 163 define 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 172 bb2: 173 %4 = zext i16 %3 to i32 174 ret i32 %4 175 } 176 177 define 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 186 bb2: 187 %4 = zext i8 %3 to i64 188 ret i64 %4 189 } 190 191 define 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 200 bb2: 201 %4 = zext i16 %3 to i64 202 ret i64 %4 203 } 204 205 define 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 214 bb2: 215 %4 = zext i32 %3 to i64 216 ret i64 %4 217 } 218 219 define 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 228 bb2: 229 %4 = sext i8 %3 to i32 230 ret i32 %4 231 } 232 233 define 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 242 bb2: 243 %4 = sext i16 %3 to i32 244 ret i32 %4 245 } 246 247 define 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 256 bb2: 257 %4 = sext i8 %3 to i64 258 ret i64 %4 259 } 260 261 define 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 270 bb2: 271 %4 = sext i16 %3 to i64 272 ret i64 %4 273 } 274 275 define 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 284 bb2: 285 %4 = sext i32 %3 to i64 286 ret i64 %4 287 } 288 289 ; Extend 290 define 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 300 bb2: 301 %5 = zext i8 %4 to i32 302 ret i32 %5 303 } 304 305 define 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 315 bb2: 316 %5 = zext i16 %4 to i32 317 ret i32 %5 318 } 319 320 define 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 330 bb2: 331 %5 = zext i8 %4 to i64 332 ret i64 %5 333 } 334 335 define 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 345 bb2: 346 %5 = zext i16 %4 to i64 347 ret i64 %5 348 } 349 350 define 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 360 bb2: 361 %5 = zext i32 %4 to i64 362 ret i64 %5 363 } 364 365 define 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 375 bb2: 376 %5 = sext i8 %4 to i32 377 ret i32 %5 378 } 379 380 define 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 390 bb2: 391 %5 = sext i16 %4 to i32 392 ret i32 %5 393 } 394 395 define 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 405 bb2: 406 %5 = sext i8 %4 to i64 407 ret i64 %5 408 } 409 410 define 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 420 bb2: 421 %5 = sext i16 %4 to i64 422 ret i64 %5 423 } 424 425 define 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 435 bb2: 436 %5 = sext i32 %4 to i64 437 ret i64 %5 438 } 439 440