diff --git a/llvm/lib/Target/VE/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td --- a/llvm/lib/Target/VE/VEInstrInfo.td +++ b/llvm/lib/Target/VE/VEInstrInfo.td @@ -1661,6 +1661,14 @@ (LEASLrii (ANDrm (LEAzii 0, 0, tglobaladdr:$in2), !add(32, 64)), 0, (tglobaladdr:$in1))>; +// Address calculation and its optimization +def : Pat<(VEhi tblockaddress:$in), (LEASLzii 0, 0, tblockaddress:$in)>; +def : Pat<(VElo tblockaddress:$in), + (ANDrm (LEAzii 0, 0, tblockaddress:$in), !add(32, 64))>; +def : Pat<(add (VEhi tblockaddress:$in1), (VElo tblockaddress:$in2)), + (LEASLrii (ANDrm (LEAzii 0, 0, tblockaddress:$in2), !add(32, 64)), 0, + (tblockaddress:$in1))>; + // GlobalTLS address calculation and its optimization def : Pat<(VEhi tglobaltlsaddr:$in), (LEASLzii 0, 0, tglobaltlsaddr:$in)>; def : Pat<(VElo tglobaltlsaddr:$in), diff --git a/llvm/lib/Target/VE/VEMCInstLower.cpp b/llvm/lib/Target/VE/VEMCInstLower.cpp --- a/llvm/lib/Target/VE/VEMCInstLower.cpp +++ b/llvm/lib/Target/VE/VEMCInstLower.cpp @@ -51,6 +51,9 @@ break; return MCOperand::createReg(MO.getReg()); + case MachineOperand::MO_BlockAddress: + return LowerSymbolOperand( + MI, MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP); case MachineOperand::MO_ConstantPoolIndex: return LowerSymbolOperand(MI, MO, AP.GetCPISymbol(MO.getIndex()), AP); case MachineOperand::MO_ExternalSymbol: diff --git a/llvm/test/CodeGen/VE/blockaddress.ll b/llvm/test/CodeGen/VE/blockaddress.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/VE/blockaddress.ll @@ -0,0 +1,25 @@ +; RUN: llc < %s -mtriple=ve | FileCheck %s + +@addr = global i8* null, align 8 + +; Function Attrs: nofree norecurse nounwind writeonly +define void @test() { +; CHECK-LABEL: test: +; CHECK: .LBB0_3: # %entry +; CHECK-NEXT: .Ltmp0: # Block address taken +; CHECK-NEXT: # %bb.1: # %test1 +; CHECK-NEXT: lea %s0, addr@lo +; CHECK-NEXT: and %s0, %s0, (32)0 +; CHECK-NEXT: lea.sl %s0, addr@hi(, %s0) +; CHECK-NEXT: lea %s1, .Ltmp0@lo +; CHECK-NEXT: and %s1, %s1, (32)0 +; CHECK-NEXT: lea.sl %s1, .Ltmp0@hi(, %s1) +; CHECK-NEXT: st %s1, (, %s0) +; CHECK-NEXT: or %s11, 0, %s9 +entry: + br label %test1 + +test1: + store i8* blockaddress(@test, %test1), i8** @addr, align 8 + ret void +}