diff --git a/lib/Target/AArch64/AArch64FastISel.cpp b/lib/Target/AArch64/AArch64FastISel.cpp index f748185bc957..8cfdab24651f 100644 --- a/lib/Target/AArch64/AArch64FastISel.cpp +++ b/lib/Target/AArch64/AArch64FastISel.cpp @@ -419,6 +419,13 @@ bool AArch64FastISel::ComputeAddress(const Value *Obj, Address &Addr) { } break; } + case Instruction::Add: + // Adds of constants are common and easy enough. + if (const ConstantInt *CI = dyn_cast(U->getOperand(1))) { + Addr.setOffset(Addr.getOffset() + (uint64_t)CI->getSExtValue()); + return ComputeAddress(U->getOperand(0), Addr); + } + break; } // Try to get this in a register if nothing else has worked. diff --git a/test/CodeGen/AArch64/fast-isel-compute-address.ll b/test/CodeGen/AArch64/fast-isel-compute-address.ll new file mode 100644 index 000000000000..f0b198c3d1f6 --- /dev/null +++ b/test/CodeGen/AArch64/fast-isel-compute-address.ll @@ -0,0 +1,23 @@ +; RUN: llc -fast-isel -fast-isel-abort -mtriple=arm64-apple-darwin < %s | FileCheck %s + +; Test simple constant offset. +define i64 @test_load1(i64 %a) { +; CHECK-LABEL: test_load1 +; CHECK: ldr x0, [x0, #16] + %1 = add i64 %a, 16 + %2 = inttoptr i64 %1 to i64* + %3 = load i64* %2 + ret i64 %3 +} + +; Test large constant offset. +define i64 @test_load2(i64 %a) { +; CHECK-LABEL: test_load2 +; CHECK: add [[REG:x[0-9]+]], x0, {{x[0-9]+}} +; CHECK: ldr x0, {{\[}}[[REG]]{{\]}} + %1 = add i64 %a, 16777216 + %2 = inttoptr i64 %1 to i64* + %3 = load i64* %2 + ret i64 %3 +} +