Fix handling of aliases to functions.

An alias to a function should use pc relative addressing.

llvm-svn: 168199
This commit is contained in:
Richard Osborne 2012-11-16 21:12:38 +00:00
parent 2c5ac70dd9
commit 9a43772783
2 changed files with 41 additions and 13 deletions

View File

@ -225,20 +225,16 @@ getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV,
{
// FIXME there is no actual debug info here
DebugLoc dl = GA.getDebugLoc();
if (isa<Function>(GV)) {
return DAG.getNode(XCoreISD::PCRelativeWrapper, dl, MVT::i32, GA);
const GlobalValue *UnderlyingGV = GV;
// If GV is an alias then use the aliasee to determine the wrapper type
if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
UnderlyingGV = GA->resolveAliasedGlobal();
if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(UnderlyingGV)) {
if (GVar->isConstant())
return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, GA);
return DAG.getNode(XCoreISD::DPRelativeWrapper, dl, MVT::i32, GA);
}
const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
if (!GVar) {
// If GV is an alias then use the aliasee to determine constness
if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
GVar = dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal());
}
bool isConst = GVar && GVar->isConstant();
if (isConst) {
return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, GA);
}
return DAG.getNode(XCoreISD::DPRelativeWrapper, dl, MVT::i32, GA);
return DAG.getNode(XCoreISD::PCRelativeWrapper, dl, MVT::i32, GA);
}
SDValue XCoreTargetLowering::

View File

@ -0,0 +1,32 @@
; RUN: llc < %s -march=xcore | FileCheck %s
declare void @a_val() nounwind
@b_val = external constant i32, section ".cp.rodata"
@c_val = external global i32
@a = alias void ()* @a_val
@b = alias i32* @b_val
@c = alias i32* @c_val
; CHECK: a_addr:
; CHECK: ldap r11, a
; CHECK: retsp
define void ()* @a_addr() nounwind {
entry:
ret void ()* @a
}
; CHECK: b_addr:
; CHECK: ldaw r11, cp[b]
; CHECK: retsp
define i32 *@b_addr() nounwind {
entry:
ret i32* @b
}
; CHECK: c_addr:
; CHECK: ldaw r0, dp[c]
; CHECK: retsp
define i32 *@c_addr() nounwind {
entry:
ret i32* @c
}