| # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py |
| # RUN: llc -mtriple=aarch64-unknown-unknown -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-FAST --allow-unused-prefixes |
| # RUN: llc -mtriple=aarch64-unknown-unknown -mattr=+addr-lsl-slow-14 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SLOW --allow-unused-prefixes |
| |
| --- | |
| define void @ldrxrox_breg_oreg(ptr %addr) { ret void } |
| define void @ldrdrox_breg_oreg(ptr %addr) { ret void } |
| define void @more_than_one_use(ptr %addr) { ret void } |
| define void @ldrhrox_shl(ptr %addr) { ret void } |
| define void @ldrwrox_shl(ptr %addr) { ret void } |
| define void @ldrxrox_shl(ptr %addr) { ret void } |
| define void @ldrdrox_shl(ptr %addr) { ret void } |
| define void @ldrqrox_shl(ptr %addr) { ret void } |
| define void @ldrxrox_mul_rhs(ptr %addr) { ret void } |
| define void @ldrdrox_mul_rhs(ptr %addr) { ret void } |
| define void @ldrxrox_mul_lhs(ptr %addr) { ret void } |
| define void @ldrdrox_mul_lhs(ptr %addr) { ret void } |
| define void @mul_not_pow_2(ptr %addr) { ret void } |
| define void @mul_wrong_pow_2(ptr %addr) { ret void } |
| define void @more_than_one_use_shl_fallback(ptr %addr) { ret void } |
| define void @ldrxrox_more_than_one_mem_use_shl(ptr %addr) { ret void } |
| define void @ldrxrox_more_than_one_use_shl(ptr %addr) { ret void } |
| define void @ldrhrox_more_than_one_mem_use_shl(ptr %addr) { ret void } |
| define void @ldrhrox_more_than_one_use_shl(ptr %addr) { ret void } |
| define void @ldrwrox_more_than_one_use_shl(ptr %addr) { ret void } |
| define void @ldrqrox_more_than_one_use_shl(ptr %addr) { ret void } |
| define void @more_than_one_use_shl_lsl(ptr %addr) { ret void } |
| define void @more_than_one_use_shl_minsize(ptr %addr) #0 { ret void } |
| define void @ldrwrox(ptr %addr) { ret void } |
| define void @ldrsrox(ptr %addr) { ret void } |
| define void @ldrhrox(ptr %addr) { ret void } |
| define void @ldbbrox(ptr %addr) { ret void } |
| define void @ldrqrox(ptr %addr) { ret void } |
| attributes #0 = { optsize } |
| ... |
| |
| --- |
| name: ldrxrox_breg_oreg |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1 |
| |
| ; CHECK-LABEL: name: ldrxrox_breg_oreg |
| ; CHECK: liveins: $x0, $x1 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 |
| ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY]], [[COPY1]], 0, 0 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: $x0 = COPY [[LDRXroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $x0 |
| %0:gpr(p0) = COPY $x0 |
| %1:gpr(s64) = COPY $x1 |
| %2:gpr(p0) = G_PTR_ADD %0, %1 |
| %4:gpr(s64) = G_LOAD %2(p0) :: (load (s64) from %ir.addr) |
| $x0 = COPY %4(s64) |
| RET_ReallyLR implicit $x0 |
| ... |
| |
| --- |
| name: ldrdrox_breg_oreg |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $d0, $x1 |
| ; CHECK-LABEL: name: ldrdrox_breg_oreg |
| ; CHECK: liveins: $d0, $x1 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $d0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 |
| ; CHECK-NEXT: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY]], [[COPY1]], 0, 0 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: $d0 = COPY [[LDRDroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $d0 |
| %0:gpr(p0) = COPY $d0 |
| %1:gpr(s64) = COPY $x1 |
| %2:gpr(p0) = G_PTR_ADD %0, %1 |
| %4:fpr(s64) = G_LOAD %2(p0) :: (load (s64) from %ir.addr) |
| $d0 = COPY %4(s64) |
| RET_ReallyLR implicit $d0 |
| ... |
| --- |
| # This shouldn't be folded, since we reuse the result of the G_PTR_ADD outside |
| # the G_LOAD |
| |
| name: more_than_one_use |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1 |
| ; CHECK-LABEL: name: more_than_one_use |
| ; CHECK: liveins: $x0, $x1 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 |
| ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64common = ADDXrr [[COPY]], [[COPY1]] |
| ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[ADDXrr]], 0 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY [[ADDXrr]] |
| ; CHECK-NEXT: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr [[COPY2]], [[LDRXui]] |
| ; CHECK-NEXT: $x0 = COPY [[ADDXrr1]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $x0 |
| %0:gpr(p0) = COPY $x0 |
| %1:gpr(s64) = COPY $x1 |
| %2:gpr(p0) = G_PTR_ADD %0, %1 |
| %4:gpr(s64) = G_LOAD %2(p0) :: (load (s64) from %ir.addr) |
| %5:gpr(s64) = G_PTRTOINT %2 |
| %6:gpr(s64) = G_ADD %5, %4 |
| $x0 = COPY %6(s64) |
| RET_ReallyLR implicit $x0 |
| |
| ... |
| --- |
| name: ldrhrox_shl |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x2 |
| liveins: $w1, $x0 |
| |
| ; CHECK-LABEL: name: ldrhrox_shl |
| ; CHECK: liveins: $x0, $x1, $x2, $w1, $x0 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 |
| ; CHECK-NEXT: [[UBFMWri:%[0-9]+]]:gpr32 = UBFMWri [[COPY1]], 9, 31 |
| ; CHECK-NEXT: [[ORRWrs:%[0-9]+]]:gpr32 = ORRWrs $wzr, [[UBFMWri]], 0 |
| ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[ORRWrs]], %subreg.sub_32 |
| ; CHECK-NEXT: [[ANDXri:%[0-9]+]]:gpr64common = ANDXri [[SUBREG_TO_REG]], 4103 |
| ; CHECK-NEXT: [[LDRHHroX:%[0-9]+]]:gpr32 = LDRHHroX [[COPY]], [[ANDXri]], 0, 1 :: (load (s16)) |
| ; CHECK-NEXT: RET_ReallyLR implicit [[LDRHHroX]] |
| %0:gpr(p0) = COPY $x0 |
| %1:gpr(s32) = COPY $w1 |
| %15:gpr(s64) = G_CONSTANT i64 9 |
| %3:gpr(s32) = G_LSHR %1, %15(s64) |
| %4:gpr(s64) = G_ZEXT %3(s32) |
| %5:gpr(s64) = G_CONSTANT i64 255 |
| %6:gpr(s64) = G_AND %4, %5 |
| %13:gpr(s64) = G_CONSTANT i64 1 |
| %8:gpr(s64) = G_SHL %6, %13(s64) |
| %9:gpr(p0) = G_PTR_ADD %0, %8(s64) |
| %12:gpr(s32) = G_LOAD %9(p0) :: (load (s16)) |
| RET_ReallyLR implicit %12 |
| ... |
| --- |
| name: ldrwrox_shl |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x2 |
| ; CHECK-LABEL: name: ldrwrox_shl |
| ; CHECK: liveins: $x0, $x1, $x2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 |
| ; CHECK-NEXT: [[LDRWroX:%[0-9]+]]:gpr32 = LDRWroX [[COPY1]], [[COPY]], 0, 1 :: (load (s32) from %ir.addr) |
| ; CHECK-NEXT: RET_ReallyLR implicit [[LDRWroX]] |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 2 |
| %2:gpr(s64) = G_SHL %0, %1(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %5:gpr(s32) = G_LOAD %4(p0) :: (load (s32) from %ir.addr) |
| RET_ReallyLR implicit %5 |
| ... |
| --- |
| name: ldrxrox_shl |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x2 |
| ; CHECK-LABEL: name: ldrxrox_shl |
| ; CHECK: liveins: $x0, $x1, $x2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 |
| ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: $x2 = COPY [[LDRXroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $x2 |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 3 |
| %2:gpr(s64) = G_SHL %0, %1(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %5:gpr(s64) = G_LOAD %4(p0) :: (load (s64) from %ir.addr) |
| $x2 = COPY %5(s64) |
| RET_ReallyLR implicit $x2 |
| |
| ... |
| --- |
| name: ldrdrox_shl |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $d2 |
| ; CHECK-LABEL: name: ldrdrox_shl |
| ; CHECK: liveins: $x0, $x1, $d2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 |
| ; CHECK-NEXT: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: $d2 = COPY [[LDRDroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $d2 |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 3 |
| %2:gpr(s64) = G_SHL %0, %1(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %5:fpr(s64) = G_LOAD %4(p0) :: (load (s64) from %ir.addr) |
| $d2 = COPY %5(s64) |
| RET_ReallyLR implicit $d2 |
| |
| ... |
| --- |
| name: ldrqrox_shl |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $d2 |
| ; CHECK-LABEL: name: ldrqrox_shl |
| ; CHECK: liveins: $x0, $x1, $d2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 |
| ; CHECK-NEXT: [[LDRQroX:%[0-9]+]]:fpr128 = LDRQroX [[COPY1]], [[COPY]], 0, 1 :: (load (s128) from %ir.addr) |
| ; CHECK-NEXT: RET_ReallyLR implicit [[LDRQroX]] |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 4 |
| %2:gpr(s64) = G_SHL %0, %1(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %5:fpr(s128) = G_LOAD %4(p0) :: (load (s128) from %ir.addr) |
| RET_ReallyLR implicit %5 |
| |
| ... |
| --- |
| name: ldrxrox_mul_rhs |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x2 |
| ; CHECK-LABEL: name: ldrxrox_mul_rhs |
| ; CHECK: liveins: $x0, $x1, $x2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 |
| ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: $x2 = COPY [[LDRXroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $x2 |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 8 |
| %2:gpr(s64) = G_MUL %0, %1(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %5:gpr(s64) = G_LOAD %4(p0) :: (load (s64) from %ir.addr) |
| $x2 = COPY %5(s64) |
| RET_ReallyLR implicit $x2 |
| |
| ... |
| --- |
| name: ldrdrox_mul_rhs |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $d2 |
| ; CHECK-LABEL: name: ldrdrox_mul_rhs |
| ; CHECK: liveins: $x0, $x1, $d2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 |
| ; CHECK-NEXT: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: $d2 = COPY [[LDRDroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $d2 |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 8 |
| %2:gpr(s64) = G_MUL %0, %1(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %5:fpr(s64) = G_LOAD %4(p0) :: (load (s64) from %ir.addr) |
| $d2 = COPY %5(s64) |
| RET_ReallyLR implicit $d2 |
| |
| ... |
| --- |
| name: ldrxrox_mul_lhs |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x2 |
| ; CHECK-LABEL: name: ldrxrox_mul_lhs |
| ; CHECK: liveins: $x0, $x1, $x2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 |
| ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: $x2 = COPY [[LDRXroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $x2 |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 8 |
| %2:gpr(s64) = G_MUL %1, %0(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %5:gpr(s64) = G_LOAD %4(p0) :: (load (s64) from %ir.addr) |
| $x2 = COPY %5(s64) |
| RET_ReallyLR implicit $x2 |
| |
| ... |
| --- |
| name: ldrdrox_mul_lhs |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $d2 |
| ; CHECK-LABEL: name: ldrdrox_mul_lhs |
| ; CHECK: liveins: $x0, $x1, $d2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 |
| ; CHECK-NEXT: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: $d2 = COPY [[LDRDroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $d2 |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 8 |
| %2:gpr(s64) = G_MUL %1, %0(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %5:fpr(s64) = G_LOAD %4(p0) :: (load (s64) from %ir.addr) |
| $d2 = COPY %5(s64) |
| RET_ReallyLR implicit $d2 |
| |
| ... |
| --- |
| # Show that we don't get a shifted load from a mul when we don't have a |
| # power of 2. (The bit isn't set on the load.) |
| |
| name: mul_not_pow_2 |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $d2 |
| ; CHECK-LABEL: name: mul_not_pow_2 |
| ; CHECK: liveins: $x0, $x1, $d2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 7 |
| ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32 |
| ; CHECK-NEXT: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[SUBREG_TO_REG]], [[COPY]], $xzr |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 |
| ; CHECK-NEXT: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[MADDXrrr]], 0, 0 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: $d2 = COPY [[LDRDroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $d2 |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 7 |
| %2:gpr(s64) = G_MUL %1, %0(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %5:fpr(s64) = G_LOAD %4(p0) :: (load (s64) from %ir.addr) |
| $d2 = COPY %5(s64) |
| RET_ReallyLR implicit $d2 |
| |
| ... |
| --- |
| # Show that we don't get a shifted load from a mul when we don't have |
| # the right power of 2. (The bit isn't set on the load.) |
| |
| name: mul_wrong_pow_2 |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $d2 |
| ; CHECK-LABEL: name: mul_wrong_pow_2 |
| ; CHECK: liveins: $x0, $x1, $d2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 16 |
| ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32 |
| ; CHECK-NEXT: [[MADDXrrr:%[0-9]+]]:gpr64 = MADDXrrr [[SUBREG_TO_REG]], [[COPY]], $xzr |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 |
| ; CHECK-NEXT: [[LDRDroX:%[0-9]+]]:fpr64 = LDRDroX [[COPY1]], [[MADDXrrr]], 0, 0 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: $d2 = COPY [[LDRDroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $d2 |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 16 |
| %2:gpr(s64) = G_MUL %1, %0(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %5:fpr(s64) = G_LOAD %4(p0) :: (load (s64) from %ir.addr) |
| $d2 = COPY %5(s64) |
| RET_ReallyLR implicit $d2 |
| |
| ... |
| --- |
| # Show that we can still fall back to the register-register addressing |
| # mode when we fail to pull in the shift. |
| |
| name: more_than_one_use_shl_fallback |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x2 |
| ; CHECK-LABEL: name: more_than_one_use_shl_fallback |
| ; CHECK: liveins: $x0, $x1, $x2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[UBFMXri:%[0-9]+]]:gpr64common = UBFMXri [[COPY]], 62, 61 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 |
| ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[UBFMXri]], 0, 0 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64common = ADDXri [[UBFMXri]], 2, 0 |
| ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[LDRXroX]], [[ADDXri]] |
| ; CHECK-NEXT: $x2 = COPY [[ADDXrr]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $x2 |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 2 |
| %2:gpr(s64) = G_SHL %0, %1(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %5:gpr(s64) = G_LOAD %4(p0) :: (load (s64) from %ir.addr) |
| %6:gpr(s64) = G_ADD %2, %1 |
| %7:gpr(s64) = G_ADD %5, %6 |
| $x2 = COPY %7(s64) |
| RET_ReallyLR implicit $x2 |
| |
| ... |
| --- |
| name: ldrxrox_more_than_one_mem_use_shl |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x2 |
| ; CHECK-LABEL: name: ldrxrox_more_than_one_mem_use_shl |
| ; CHECK: liveins: $x0, $x1, $x2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 |
| ; CHECK-NEXT: [[UBFMWri:%[0-9]+]]:gpr32 = UBFMWri [[COPY1]], 9, 31 |
| ; CHECK-NEXT: [[ORRWrs:%[0-9]+]]:gpr32 = ORRWrs $wzr, [[UBFMWri]], 0 |
| ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[ORRWrs]], %subreg.sub_32 |
| ; CHECK-NEXT: [[ANDXri:%[0-9]+]]:gpr64common = ANDXri [[SUBREG_TO_REG]], 4103 |
| ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY]], [[ANDXri]], 0, 1 :: (load (s64)) |
| ; CHECK-NEXT: [[LDRXroX1:%[0-9]+]]:gpr64 = LDRXroX [[COPY]], [[ANDXri]], 0, 1 :: (load (s64)) |
| ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[LDRXroX]], [[LDRXroX1]] |
| ; CHECK-NEXT: RET_ReallyLR implicit [[ADDXrr]] |
| %0:gpr(p0) = COPY $x0 |
| %1:gpr(s32) = COPY $w1 |
| %15:gpr(s64) = G_CONSTANT i64 9 |
| %3:gpr(s32) = G_LSHR %1, %15(s64) |
| %4:gpr(s64) = G_ZEXT %3(s32) |
| %5:gpr(s64) = G_CONSTANT i64 255 |
| %6:gpr(s64) = G_AND %4, %5 |
| %13:gpr(s64) = G_CONSTANT i64 3 |
| %8:gpr(s64) = G_SHL %6, %13(s64) |
| %9:gpr(p0) = G_PTR_ADD %0, %8(s64) |
| %12:gpr(s64) = G_LOAD %9(p0) :: (load (s64)) |
| %17:gpr(s64) = G_LOAD %9(p0) :: (load (s64)) |
| %18:gpr(s64) = G_ADD %12, %17 |
| RET_ReallyLR implicit %18 |
| |
| ... |
| --- |
| # Show that when the GEP is used both inside and outside a memory op, we only fold the memory op. |
| |
| name: ldrxrox_more_than_one_use_shl |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x2 |
| ; CHECK-LABEL: name: ldrxrox_more_than_one_use_shl |
| ; CHECK: liveins: $x0, $x1, $x2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[UBFMXri:%[0-9]+]]:gpr64common = UBFMXri [[COPY]], 61, 60 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64common = COPY $x1 |
| ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY [[COPY1]] |
| ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[COPY2]], [[UBFMXri]] |
| ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64common = ADDXri [[UBFMXri]], 3, 0 |
| ; CHECK-NEXT: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr [[LDRXroX]], [[ADDXri]] |
| ; CHECK-NEXT: [[ADDXrr2:%[0-9]+]]:gpr64 = ADDXrr [[ADDXrr]], [[ADDXrr1]] |
| ; CHECK-NEXT: $x2 = COPY [[ADDXrr2]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $x2 |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 3 |
| %2:gpr(s64) = G_SHL %0, %1(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %5:gpr(s64) = G_LOAD %4(p0) :: (load (s64) from %ir.addr) |
| %6:gpr(s64) = G_ADD %2, %1 |
| %7:gpr(s64) = G_ADD %5, %6 |
| %8:gpr(s64) = G_PTRTOINT %4 |
| %9:gpr(s64) = G_ADD %8, %7 |
| $x2 = COPY %9(s64) |
| RET_ReallyLR implicit $x2 |
| |
| ... |
| --- |
| # Fold SHL into LSL for mem ops. Do not fold if the target has LSLSLOW14. |
| name: ldrhrox_more_than_one_mem_use_shl |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x2 |
| liveins: $w1, $x0 |
| |
| ; CHECK-FAST-LABEL: name: ldrhrox_more_than_one_mem_use_shl |
| ; CHECK-FAST: liveins: $x0, $x1, $x2, $w1, $x0 |
| ; CHECK-FAST-NEXT: {{ $}} |
| ; CHECK-FAST-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 |
| ; CHECK-FAST-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 |
| ; CHECK-FAST-NEXT: [[UBFMWri:%[0-9]+]]:gpr32 = UBFMWri [[COPY1]], 9, 31 |
| ; CHECK-FAST-NEXT: [[ORRWrs:%[0-9]+]]:gpr32 = ORRWrs $wzr, [[UBFMWri]], 0 |
| ; CHECK-FAST-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[ORRWrs]], %subreg.sub_32 |
| ; CHECK-FAST-NEXT: [[ANDXri:%[0-9]+]]:gpr64common = ANDXri [[SUBREG_TO_REG]], 4103 |
| ; CHECK-FAST-NEXT: [[LDRHHroX:%[0-9]+]]:gpr32 = LDRHHroX [[COPY]], [[ANDXri]], 0, 1 :: (load (s16)) |
| ; CHECK-FAST-NEXT: [[LDRHHroX1:%[0-9]+]]:gpr32 = LDRHHroX [[COPY]], [[ANDXri]], 0, 1 :: (load (s16)) |
| ; CHECK-FAST-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[LDRHHroX]], [[LDRHHroX1]] |
| ; CHECK-FAST-NEXT: RET_ReallyLR implicit [[ADDWrr]] |
| ; |
| ; CHECK-SLOW-LABEL: name: ldrhrox_more_than_one_mem_use_shl |
| ; CHECK-SLOW: liveins: $x0, $x1, $x2, $w1, $x0 |
| ; CHECK-SLOW-NEXT: {{ $}} |
| ; CHECK-SLOW-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-SLOW-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 |
| ; CHECK-SLOW-NEXT: [[UBFMWri:%[0-9]+]]:gpr32 = UBFMWri [[COPY1]], 9, 31 |
| ; CHECK-SLOW-NEXT: [[ORRWrs:%[0-9]+]]:gpr32 = ORRWrs $wzr, [[UBFMWri]], 0 |
| ; CHECK-SLOW-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[ORRWrs]], %subreg.sub_32 |
| ; CHECK-SLOW-NEXT: [[COPY2:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]].sub_32 |
| ; CHECK-SLOW-NEXT: [[COPY3:%[0-9]+]]:gpr32 = COPY [[COPY2]] |
| ; CHECK-SLOW-NEXT: [[COPY4:%[0-9]+]]:gpr64common = COPY [[COPY]] |
| ; CHECK-SLOW-NEXT: [[ADDXrx:%[0-9]+]]:gpr64sp = ADDXrx [[COPY4]], [[COPY3]], 1 |
| ; CHECK-SLOW-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[ADDXrx]], 0 :: (load (s16)) |
| ; CHECK-SLOW-NEXT: [[LDRHHui1:%[0-9]+]]:gpr32 = LDRHHui [[ADDXrx]], 0 :: (load (s16)) |
| ; CHECK-SLOW-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[LDRHHui]], [[LDRHHui1]] |
| ; CHECK-SLOW-NEXT: RET_ReallyLR implicit [[ADDWrr]] |
| %0:gpr(p0) = COPY $x0 |
| %1:gpr(s32) = COPY $w1 |
| %15:gpr(s64) = G_CONSTANT i64 9 |
| %3:gpr(s32) = G_LSHR %1, %15(s64) |
| %4:gpr(s64) = G_ZEXT %3(s32) |
| %5:gpr(s64) = G_CONSTANT i64 255 |
| %6:gpr(s64) = G_AND %4, %5 |
| %13:gpr(s64) = G_CONSTANT i64 1 |
| %8:gpr(s64) = G_SHL %6, %13(s64) |
| %9:gpr(p0) = G_PTR_ADD %0, %8(s64) |
| %12:gpr(s32) = G_LOAD %9(p0) :: (load (s16)) |
| %17:gpr(s32) = G_LOAD %9(p0) :: (load (s16)) |
| %18:gpr(s32) = G_ADD %12, %17 |
| RET_ReallyLR implicit %18 |
| ... |
| --- |
| # Fold SHL into LSL for memory ops. Do not fold if the target has LSLSLOW14. |
| name: ldrhrox_more_than_one_use_shl |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x2 |
| liveins: $w1, $x0 |
| |
| ; CHECK-FAST-LABEL: name: ldrhrox_more_than_one_use_shl |
| ; CHECK-FAST: liveins: $x0, $x1, $x2, $w1, $x0 |
| ; CHECK-FAST-NEXT: {{ $}} |
| ; CHECK-FAST-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 |
| ; CHECK-FAST-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 |
| ; CHECK-FAST-NEXT: [[UBFMWri:%[0-9]+]]:gpr32 = UBFMWri [[COPY1]], 9, 31 |
| ; CHECK-FAST-NEXT: [[ORRWrs:%[0-9]+]]:gpr32 = ORRWrs $wzr, [[UBFMWri]], 0 |
| ; CHECK-FAST-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[ORRWrs]], %subreg.sub_32 |
| ; CHECK-FAST-NEXT: [[ANDXri:%[0-9]+]]:gpr64common = ANDXri [[SUBREG_TO_REG]], 4103 |
| ; CHECK-FAST-NEXT: [[LDRHHroX:%[0-9]+]]:gpr32 = LDRHHroX [[COPY]], [[ANDXri]], 0, 1 :: (load (s16)) |
| ; CHECK-FAST-NEXT: [[LDRHHroX1:%[0-9]+]]:gpr32 = LDRHHroX [[COPY]], [[ANDXri]], 0, 1 :: (load (s16)) |
| ; CHECK-FAST-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[LDRHHroX]], [[LDRHHroX1]] |
| ; CHECK-FAST-NEXT: RET_ReallyLR implicit [[ADDWrr]] |
| ; |
| ; CHECK-SLOW-LABEL: name: ldrhrox_more_than_one_use_shl |
| ; CHECK-SLOW: liveins: $x0, $x1, $x2, $w1, $x0 |
| ; CHECK-SLOW-NEXT: {{ $}} |
| ; CHECK-SLOW-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-SLOW-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 |
| ; CHECK-SLOW-NEXT: [[UBFMWri:%[0-9]+]]:gpr32 = UBFMWri [[COPY1]], 9, 31 |
| ; CHECK-SLOW-NEXT: [[ORRWrs:%[0-9]+]]:gpr32 = ORRWrs $wzr, [[UBFMWri]], 0 |
| ; CHECK-SLOW-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[ORRWrs]], %subreg.sub_32 |
| ; CHECK-SLOW-NEXT: [[COPY2:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]].sub_32 |
| ; CHECK-SLOW-NEXT: [[COPY3:%[0-9]+]]:gpr32 = COPY [[COPY2]] |
| ; CHECK-SLOW-NEXT: [[COPY4:%[0-9]+]]:gpr64common = COPY [[COPY]] |
| ; CHECK-SLOW-NEXT: [[ADDXrx:%[0-9]+]]:gpr64sp = ADDXrx [[COPY4]], [[COPY3]], 1 |
| ; CHECK-SLOW-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[ADDXrx]], 0 :: (load (s16)) |
| ; CHECK-SLOW-NEXT: [[LDRHHui1:%[0-9]+]]:gpr32 = LDRHHui [[ADDXrx]], 0 :: (load (s16)) |
| ; CHECK-SLOW-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[LDRHHui]], [[LDRHHui1]] |
| ; CHECK-SLOW-NEXT: RET_ReallyLR implicit [[ADDWrr]] |
| %0:gpr(p0) = COPY $x0 |
| %1:gpr(s32) = COPY $w1 |
| %15:gpr(s64) = G_CONSTANT i64 9 |
| %3:gpr(s32) = G_LSHR %1, %15(s64) |
| %4:gpr(s64) = G_ZEXT %3(s32) |
| %5:gpr(s64) = G_CONSTANT i64 255 |
| %6:gpr(s64) = G_AND %4, %5 |
| %13:gpr(s64) = G_CONSTANT i64 1 |
| %8:gpr(s64) = G_SHL %6, %13(s64) |
| %9:gpr(p0) = G_PTR_ADD %0, %8(s64) |
| %12:gpr(s32) = G_LOAD %9(p0) :: (load (s16)) |
| %17:gpr(s32) = G_LOAD %9(p0) :: (load (s16)) |
| %18:gpr(s32) = G_ADD %12, %17 |
| RET_ReallyLR implicit %18 |
| ... |
| --- |
| # Fold SHL into LSL for memory ops. |
| name: ldrwrox_more_than_one_use_shl |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x2 |
| ; CHECK-LABEL: name: ldrwrox_more_than_one_use_shl |
| ; CHECK: liveins: $x0, $x1, $x2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[UBFMXri:%[0-9]+]]:gpr64common = UBFMXri [[COPY]], 62, 61 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64common = COPY $x1 |
| ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY [[COPY1]] |
| ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[COPY2]], [[UBFMXri]] |
| ; CHECK-NEXT: [[LDRWroX:%[0-9]+]]:gpr32 = LDRWroX [[COPY1]], [[COPY]], 0, 1 :: (load (s32) from %ir.addr) |
| ; CHECK-NEXT: [[ORRWrs:%[0-9]+]]:gpr32 = ORRWrs $wzr, [[LDRWroX]], 0 |
| ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG 0, [[ORRWrs]], %subreg.sub_32 |
| ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64common = ADDXri [[UBFMXri]], 2, 0 |
| ; CHECK-NEXT: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr [[SUBREG_TO_REG]], [[ADDXri]] |
| ; CHECK-NEXT: [[ADDXrr2:%[0-9]+]]:gpr64 = ADDXrr [[ADDXrr]], [[ADDXrr1]] |
| ; CHECK-NEXT: $x2 = COPY [[ADDXrr2]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $x2 |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 2 |
| %2:gpr(s64) = G_SHL %0, %1(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %20:gpr(s32) = G_LOAD %4(p0) :: (load (s32) from %ir.addr) |
| %5:gpr(s64) = G_ZEXT %20 |
| %6:gpr(s64) = G_ADD %2, %1 |
| %7:gpr(s64) = G_ADD %5, %6 |
| %8:gpr(s64) = G_PTRTOINT %4 |
| %9:gpr(s64) = G_ADD %8, %7 |
| $x2 = COPY %9(s64) |
| RET_ReallyLR implicit $x2 |
| ... |
| --- |
| # Fold SHL into LSL for memory ops. Do not fold if the target has LSLSLOW14. |
| name: ldrqrox_more_than_one_use_shl |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x2 |
| ; CHECK-FAST-LABEL: name: ldrqrox_more_than_one_use_shl |
| ; CHECK-FAST: liveins: $x0, $x1, $x2 |
| ; CHECK-FAST-NEXT: {{ $}} |
| ; CHECK-FAST-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-FAST-NEXT: [[UBFMXri:%[0-9]+]]:gpr64common = UBFMXri [[COPY]], 60, 59 |
| ; CHECK-FAST-NEXT: [[COPY1:%[0-9]+]]:gpr64common = COPY $x1 |
| ; CHECK-FAST-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY [[COPY1]] |
| ; CHECK-FAST-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[COPY2]], [[UBFMXri]] |
| ; CHECK-FAST-NEXT: [[LDRQroX:%[0-9]+]]:fpr128 = LDRQroX [[COPY1]], [[COPY]], 0, 1 :: (load (s128) from %ir.addr) |
| ; CHECK-FAST-NEXT: [[ADDXri:%[0-9]+]]:gpr64common = ADDXri [[UBFMXri]], 4, 0 |
| ; CHECK-FAST-NEXT: [[COPY3:%[0-9]+]]:fpr64 = COPY [[LDRQroX]].dsub |
| ; CHECK-FAST-NEXT: [[COPY4:%[0-9]+]]:gpr64 = COPY [[COPY3]] |
| ; CHECK-FAST-NEXT: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr [[COPY4]], [[ADDXri]] |
| ; CHECK-FAST-NEXT: [[ADDXrr2:%[0-9]+]]:gpr64 = ADDXrr [[ADDXrr]], [[ADDXrr1]] |
| ; CHECK-FAST-NEXT: RET_ReallyLR implicit [[ADDXrr2]] |
| ; |
| ; CHECK-SLOW-LABEL: name: ldrqrox_more_than_one_use_shl |
| ; CHECK-SLOW: liveins: $x0, $x1, $x2 |
| ; CHECK-SLOW-NEXT: {{ $}} |
| ; CHECK-SLOW-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-SLOW-NEXT: [[UBFMXri:%[0-9]+]]:gpr64common = UBFMXri [[COPY]], 60, 59 |
| ; CHECK-SLOW-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 |
| ; CHECK-SLOW-NEXT: [[ADDXrr:%[0-9]+]]:gpr64common = ADDXrr [[COPY1]], [[UBFMXri]] |
| ; CHECK-SLOW-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADDXrr]], 0 :: (load (s128) from %ir.addr) |
| ; CHECK-SLOW-NEXT: [[ADDXri:%[0-9]+]]:gpr64common = ADDXri [[UBFMXri]], 4, 0 |
| ; CHECK-SLOW-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[LDRQui]].dsub |
| ; CHECK-SLOW-NEXT: [[COPY3:%[0-9]+]]:gpr64 = COPY [[COPY2]] |
| ; CHECK-SLOW-NEXT: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr [[COPY3]], [[ADDXri]] |
| ; CHECK-SLOW-NEXT: [[COPY4:%[0-9]+]]:gpr64 = COPY [[ADDXrr]] |
| ; CHECK-SLOW-NEXT: [[ADDXrr2:%[0-9]+]]:gpr64 = ADDXrr [[COPY4]], [[ADDXrr1]] |
| ; CHECK-SLOW-NEXT: RET_ReallyLR implicit [[ADDXrr2]] |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 4 |
| %2:gpr(s64) = G_SHL %0, %1(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %20:fpr(s128) = G_LOAD %4(p0) :: (load (s128) from %ir.addr) |
| %6:gpr(s64) = G_ADD %2, %1 |
| %200:fpr(s64) = G_TRUNC %20 |
| %2000:gpr(s64) = COPY %200 |
| %7:gpr(s64) = G_ADD %2000, %6 |
| %8:gpr(s64) = G_PTRTOINT %4 |
| %9:gpr(s64) = G_ADD %8, %7 |
| RET_ReallyLR implicit %9 |
| ... |
| --- |
| # Show that when we have a fastpath for shift-left, we perform the folding |
| # if it has more than one use. |
| |
| name: more_than_one_use_shl_lsl |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x2 |
| ; CHECK-LABEL: name: more_than_one_use_shl_lsl |
| ; CHECK: liveins: $x0, $x1, $x2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 |
| ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: [[LDRXroX1:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[LDRXroX]], [[LDRXroX1]] |
| ; CHECK-NEXT: $x2 = COPY [[ADDXrr]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $x2 |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 3 |
| %2:gpr(s64) = G_SHL %0, %1(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %5:gpr(s64) = G_LOAD %4(p0) :: (load (s64) from %ir.addr) |
| %6:gpr(s64) = G_LOAD %4(p0) :: (load (s64) from %ir.addr) |
| %7:gpr(s64) = G_ADD %5, %6 |
| $x2 = COPY %7(s64) |
| RET_ReallyLR implicit $x2 |
| |
| ... |
| --- |
| # Show that when we're optimizing for size, we'll do the folding no matter |
| # what. |
| |
| name: more_than_one_use_shl_minsize |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1, $x2 |
| ; CHECK-LABEL: name: more_than_one_use_shl_minsize |
| ; CHECK: liveins: $x0, $x1, $x2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 |
| ; CHECK-NEXT: [[UBFMXri:%[0-9]+]]:gpr64common = UBFMXri [[COPY]], 61, 60 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64common = COPY $x1 |
| ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY [[COPY1]] |
| ; CHECK-NEXT: [[ADDXrs:%[0-9]+]]:gpr64 = ADDXrs [[COPY2]], [[COPY]], 3 |
| ; CHECK-NEXT: [[LDRXroX:%[0-9]+]]:gpr64 = LDRXroX [[COPY1]], [[COPY]], 0, 1 :: (load (s64) from %ir.addr) |
| ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64common = ADDXri [[UBFMXri]], 3, 0 |
| ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[LDRXroX]], [[ADDXri]] |
| ; CHECK-NEXT: [[ADDXrr1:%[0-9]+]]:gpr64 = ADDXrr [[ADDXrs]], [[ADDXrr]] |
| ; CHECK-NEXT: $x2 = COPY [[ADDXrr1]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $x2 |
| %0:gpr(s64) = COPY $x0 |
| %1:gpr(s64) = G_CONSTANT i64 3 |
| %2:gpr(s64) = G_SHL %0, %1(s64) |
| %3:gpr(p0) = COPY $x1 |
| %4:gpr(p0) = G_PTR_ADD %3, %2 |
| %5:gpr(s64) = G_LOAD %4(p0) :: (load (s64) from %ir.addr) |
| %6:gpr(s64) = G_ADD %2, %1 |
| %7:gpr(s64) = G_ADD %5, %6 |
| %8:gpr(s64) = G_PTRTOINT %4 |
| %9:gpr(s64) = G_ADD %8, %7 |
| $x2 = COPY %9(s64) |
| RET_ReallyLR implicit $x2 |
| ... |
| --- |
| name: ldrwrox |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1 |
| ; CHECK-LABEL: name: ldrwrox |
| ; CHECK: liveins: $x0, $x1 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 |
| ; CHECK-NEXT: [[LDRWroX:%[0-9]+]]:gpr32 = LDRWroX [[COPY]], [[COPY1]], 0, 0 :: (load (s32) from %ir.addr) |
| ; CHECK-NEXT: $w2 = COPY [[LDRWroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $w2 |
| %0:gpr(p0) = COPY $x0 |
| %1:gpr(s64) = COPY $x1 |
| %2:gpr(p0) = G_PTR_ADD %0, %1 |
| %4:gpr(s32) = G_LOAD %2(p0) :: (load (s32) from %ir.addr) |
| $w2 = COPY %4(s32) |
| RET_ReallyLR implicit $w2 |
| ... |
| --- |
| name: ldrsrox |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $d0, $x1 |
| ; CHECK-LABEL: name: ldrsrox |
| ; CHECK: liveins: $d0, $x1 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $d0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 |
| ; CHECK-NEXT: [[LDRSroX:%[0-9]+]]:fpr32 = LDRSroX [[COPY]], [[COPY1]], 0, 0 :: (load (s32) from %ir.addr) |
| ; CHECK-NEXT: $s2 = COPY [[LDRSroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $h2 |
| %0:gpr(p0) = COPY $d0 |
| %1:gpr(s64) = COPY $x1 |
| %2:gpr(p0) = G_PTR_ADD %0, %1 |
| %4:fpr(s32) = G_LOAD %2(p0) :: (load (s32) from %ir.addr) |
| $s2 = COPY %4(s32) |
| RET_ReallyLR implicit $h2 |
| ... |
| --- |
| name: ldrhrox |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1 |
| ; CHECK-LABEL: name: ldrhrox |
| ; CHECK: liveins: $x0, $x1 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 |
| ; CHECK-NEXT: [[LDRHroX:%[0-9]+]]:fpr16 = LDRHroX [[COPY]], [[COPY1]], 0, 0 :: (load (s16) from %ir.addr) |
| ; CHECK-NEXT: $h2 = COPY [[LDRHroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $h2 |
| %0:gpr(p0) = COPY $x0 |
| %1:gpr(s64) = COPY $x1 |
| %2:gpr(p0) = G_PTR_ADD %0, %1 |
| %4:fpr(s16) = G_LOAD %2(p0) :: (load (s16) from %ir.addr) |
| $h2 = COPY %4(s16) |
| RET_ReallyLR implicit $h2 |
| ... |
| --- |
| name: ldbbrox |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $x0, $x1 |
| ; CHECK-LABEL: name: ldbbrox |
| ; CHECK: liveins: $x0, $x1 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 |
| ; CHECK-NEXT: [[LDRBBroX:%[0-9]+]]:gpr32 = LDRBBroX [[COPY]], [[COPY1]], 0, 0 :: (load (s8) from %ir.addr) |
| ; CHECK-NEXT: $w2 = COPY [[LDRBBroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $w2 |
| %0:gpr(p0) = COPY $x0 |
| %1:gpr(s64) = COPY $x1 |
| %2:gpr(p0) = G_PTR_ADD %0, %1 |
| %4:gpr(s32) = G_LOAD %2(p0) :: (load (s8) from %ir.addr) |
| $w2 = COPY %4(s32) |
| RET_ReallyLR implicit $w2 |
| ... |
| --- |
| name: ldrqrox |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $d0, $x1 |
| ; CHECK-LABEL: name: ldrqrox |
| ; CHECK: liveins: $d0, $x1 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $d0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 |
| ; CHECK-NEXT: [[LDRQroX:%[0-9]+]]:fpr128 = LDRQroX [[COPY]], [[COPY1]], 0, 0 :: (load (<2 x s64>) from %ir.addr) |
| ; CHECK-NEXT: $q0 = COPY [[LDRQroX]] |
| ; CHECK-NEXT: RET_ReallyLR implicit $q0 |
| %0:gpr(p0) = COPY $d0 |
| %1:gpr(s64) = COPY $x1 |
| %2:gpr(p0) = G_PTR_ADD %0, %1 |
| %4:fpr(<2 x s64>) = G_LOAD %2(p0) :: (load (<2 x s64>) from %ir.addr) |
| $q0 = COPY %4(<2 x s64>) |
| RET_ReallyLR implicit $q0 |