XCore target: fix handling of unsized global arrays in large code model
authorRobert Lytton <robert@xmos.com>
Mon, 6 Jan 2014 14:20:32 +0000 (14:20 +0000)
committerRobert Lytton <robert@xmos.com>
Mon, 6 Jan 2014 14:20:32 +0000 (14:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198609 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/XCore/XCoreISelLowering.cpp
test/CodeGen/XCore/codemodel.ll

index 668a2486396126a1abd57524de78ddba1e7a9ef5..c6cbf51202c78aac8294d192ccaeb1a4df460c74 100644 (file)
@@ -268,6 +268,18 @@ getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV,
   return DAG.getNode(XCoreISD::PCRelativeWrapper, dl, MVT::i32, GA);
 }
 
+static bool IsSmallObject(const GlobalValue *GV, const XCoreTargetLowering &XTL) {
+  if (XTL.getTargetMachine().getCodeModel() == CodeModel::Small)
+    return true;
+
+  Type *ObjType = GV->getType()->getPointerElementType();
+  if (!ObjType->isSized())
+    return false;
+
+  unsigned ObjSize = XTL.getDataLayout()->getTypeAllocSize(ObjType);
+  return ObjSize < CodeModelLargeSize && ObjSize != 0;
+}
+
 SDValue XCoreTargetLowering::
 LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
 {
@@ -275,10 +287,7 @@ LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
   const GlobalValue *GV = GN->getGlobal();
   SDLoc DL(GN);
   int64_t Offset = GN->getOffset();
-  Type *ObjType = GV->getType()->getPointerElementType();
-  if (getTargetMachine().getCodeModel() == CodeModel::Small ||
-      !ObjType->isSized() ||
-      getDataLayout()->getTypeAllocSize(ObjType) < CodeModelLargeSize) {
+  if (IsSmallObject(GV, *this)) {
     // We can only fold positive offsets that are a multiple of the word size.
     int64_t FoldedOffset = std::max(Offset & ~3, (int64_t)0);
     SDValue GA = DAG.getTargetGlobalAddress(GV, DL, MVT::i32, FoldedOffset);
index 31fbbca250c21ddb45c79fa467a8ea9b0d9485d2..cc532ea7defdecad20d997bc046bcd9114b3f9f9 100644 (file)
@@ -35,6 +35,7 @@ entry:
   ret [50000 x i32]* %Addr
 }
 
+
 ; CHECK: .section  .cp.rodata.cst4,"aMc",@progbits,4
 ; CHECK: .long 65536
 ; CHECK: .text
@@ -115,6 +116,46 @@ entry:
   ret i32 %16
 }
 
+
+; CHECK-LABEL: UnknownSize:
+; CHECK: ldw r0, dp[NoSize+40]
+; CHECK-NEXT: retsp 0
+;
+; LARGE: .section .cp.rodata,"ac",@progbits
+; LARGE: .LCPI{{[0-9_]*}}
+; LARGE-NEXT: .long NoSize
+; LARGE-NEXT: .text
+; LARGE-LABEL: UnknownSize:
+; LARGE: ldw r0, cp[.LCPI{{[0-9_]*}}]
+; LARGE-NEXT: ldw r0, r0[0]
+; LARGE-NEXT: retsp 0
+@NoSize = external global [0 x i32]
+define i32 @UnknownSize() nounwind {
+entry:
+  %0 = load i32* getelementptr inbounds ([0 x i32]* @NoSize, i32 0, i32 10)
+  ret i32 %0
+}
+
+
+; CHECK-LABEL: UnknownStruct:
+; CHECK: ldaw r0, dp[Unknown]
+; CHECK-NEXT: retsp 0
+;
+; LARGE: .section .cp.rodata,"ac",@progbits
+; LARGE: .LCPI{{[0-9_]*}}
+; LARGE-NEXT: .long Unknown
+; LARGE-NEXT: .text
+; LARGE-LABEL: UnknownStruct:
+; LARGE: ldw r0, cp[.LCPI{{[0-9_]*}}]
+; LARGE-NEXT: retsp 0
+%Struct = type opaque
+@Unknown = external global %Struct
+define %Struct* @UnknownStruct() nounwind {
+entry:
+  ret %Struct* @Unknown
+}
+
+
 ; CHECK: .section .dp.bss,"awd",@nobits
 ; CHECK-LABEL: l:
 ; CHECK: .space 400