diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -3632,6 +3632,7 @@ GlobalAddressSDNode *GA; ConstantSDNode *C; + BlockAddressSDNode *BA; uint64_t Offset = 0; // Match (GA) or (C) or (GA+C) or (GA-C) or ((GA+C)+C) or (((GA+C)+C)+C), @@ -3659,6 +3660,12 @@ Ops.push_back(DAG.getTargetConstant(Offset + ExtVal, SDLoc(C), MVT::i64)); return; + } else if ((BA = dyn_cast(Op)) && + ConstraintLetter != 'n') { + Ops.push_back(DAG.getTargetBlockAddress( + BA->getBlockAddress(), BA->getValueType(0), + Offset + BA->getOffset(), BA->getTargetFlags())); + return; } else { const unsigned OpCode = Op.getOpcode(); if (OpCode == ISD::ADD || OpCode == ISD::SUB) { diff --git a/llvm/test/CodeGen/AArch64/inline-asm-blockaddress.ll b/llvm/test/CodeGen/AArch64/inline-asm-blockaddress.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/inline-asm-blockaddress.ll @@ -0,0 +1,12 @@ +; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s +; CHECK-LABEL: foo: +; CHECK: TEST .Ltmp0 +define void @foo() { +entry: + br label %bar +bar: + call void asm sideeffect "#TEST $0", "i,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@foo, %bar)) + ret void +indirectgoto: + indirectbr i8* undef, [label %bar] +}