R600: Error on initializer for LDS.
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Thu, 13 Nov 2014 19:56:13 +0000 (19:56 +0000)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Thu, 13 Nov 2014 19:56:13 +0000 (19:56 +0000)
Also give a proper error for other address spaces.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221917 91177308-0d34-0410-b5e6-96231b3b80d8

16 files changed:
lib/Target/R600/AMDGPUISelLowering.cpp
test/CodeGen/R600/32-bit-local-address-space.ll
test/CodeGen/R600/ds_read2.ll
test/CodeGen/R600/ds_read2st64.ll
test/CodeGen/R600/ds_write2.ll
test/CodeGen/R600/ds_write2st64.ll
test/CodeGen/R600/global-zero-initializer.ll [new file with mode: 0644]
test/CodeGen/R600/lds-initializer.ll [new file with mode: 0644]
test/CodeGen/R600/lds-output-queue.ll
test/CodeGen/R600/lds-size.ll
test/CodeGen/R600/lds-zero-initializer.ll [new file with mode: 0644]
test/CodeGen/R600/load.ll
test/CodeGen/R600/local-memory-two-objects.ll
test/CodeGen/R600/local-memory.ll
test/CodeGen/R600/missing-store.ll
test/CodeGen/R600/shl_add_ptr.ll

index b5aa8b4b26d7fc8b305b6fa6e8d000963bf89823..81192b7014d53367f7887f0a343fc62d043f1949 100644 (file)
@@ -691,6 +691,17 @@ SDValue AMDGPUTargetLowering::LowerConstantInitializer(const Constant* Init,
   llvm_unreachable("Unhandled constant initializer");
 }
 
+static bool hasDefinedInitializer(const GlobalValue *GV) {
+  const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
+  if (!GVar || !GVar->hasInitializer())
+    return false;
+
+  if (isa<UndefValue>(GVar->getInitializer()))
+    return false;
+
+  return true;
+}
+
 SDValue AMDGPUTargetLowering::LowerGlobalAddress(AMDGPUMachineFunction* MFI,
                                                  SDValue Op,
                                                  SelectionDAG &DAG) const {
@@ -700,13 +711,15 @@ SDValue AMDGPUTargetLowering::LowerGlobalAddress(AMDGPUMachineFunction* MFI,
   const GlobalValue *GV = G->getGlobal();
 
   switch (G->getAddressSpace()) {
-  default: llvm_unreachable("Global Address lowering not implemented for this "
-                            "address space");
   case AMDGPUAS::LOCAL_ADDRESS: {
     // XXX: What does the value of G->getOffset() mean?
     assert(G->getOffset() == 0 &&
          "Do not know what to do with an non-zero offset");
 
+    // TODO: We could emit code to handle the initialization somewhere.
+    if (hasDefinedInitializer(GV))
+      break;
+
     unsigned Offset;
     if (MFI->LocalMemoryObjects.count(GV) == 0) {
       uint64_t Size = TD->getTypeAllocSize(GV->getType()->getElementType());
@@ -760,6 +773,12 @@ SDValue AMDGPUTargetLowering::LowerGlobalAddress(AMDGPUMachineFunction* MFI,
     return DAG.getZExtOrTrunc(InitPtr, SDLoc(Op), ConstPtrVT);
   }
   }
+
+  const Function &Fn = *DAG.getMachineFunction().getFunction();
+  DiagnosticInfoUnsupported BadInit(Fn,
+                                    "initializer for address space");
+  DAG.getContext()->diagnose(BadInit);
+  return SDValue();
 }
 
 SDValue AMDGPUTargetLowering::LowerCONCAT_VECTORS(SDValue Op,
index ee397aa8192f07ccc2801a6751aa30b8e6a53b89..4ff2762284235733842ad33212558afaae870f2b 100644 (file)
@@ -77,7 +77,7 @@ define void @mul_32bit_ptr(float addrspace(1)* %out, [3 x float] addrspace(3)* %
   ret void
 }
 
-@g_lds = addrspace(3) global float zeroinitializer, align 4
+@g_lds = addrspace(3) global float undef, align 4
 
 ; FUNC-LABEL: {{^}}infer_ptr_alignment_global_offset:
 ; SI: v_mov_b32_e32 [[REG:v[0-9]+]], 0
@@ -89,8 +89,8 @@ define void @infer_ptr_alignment_global_offset(float addrspace(1)* %out, i32 %ti
 }
 
 
-@ptr = addrspace(3) global i32 addrspace(3)* null
-@dst = addrspace(3) global [16384 x i32] zeroinitializer
+@ptr = addrspace(3) global i32 addrspace(3)* undef
+@dst = addrspace(3) global [16384 x i32] undef
 
 ; FUNC-LABEL: {{^}}global_ptr:
 ; SI: ds_write_b32
index b431b5fe97c266273dc6cd3afdab9800c0c40fd9..6e0c8be373a74a4803e6f465433f0727fb899c79 100644 (file)
@@ -3,8 +3,8 @@
 ; FIXME: We don't get cases where the address was an SGPR because we
 ; get a copy to the address register for each one.
 
-@lds = addrspace(3) global [512 x float] zeroinitializer, align 4
- @lds.f64 = addrspace(3) global [512 x double] zeroinitializer, align 8
+@lds = addrspace(3) global [512 x float] undef, align 4
+ @lds.f64 = addrspace(3) global [512 x double] undef, align 8
 
 ; SI-LABEL: @simple_read2_f32
 ; SI: ds_read2_b32 v{{\[}}[[LO_VREG:[0-9]+]]:[[HI_VREG:[0-9]+]]{{\]}}, v{{[0-9]+}} offset0:0 offset1:8
@@ -382,7 +382,7 @@ define void @misaligned_read2_f64(double addrspace(1)* %out, double addrspace(3)
   ret void
 }
 
-@foo = addrspace(3) global [4 x i32] zeroinitializer, align 4
+@foo = addrspace(3) global [4 x i32] undef, align 4
 
 ; SI-LABEL: @load_constant_adjacent_offsets
 ; SI: v_mov_b32_e32 [[ZERO:v[0-9]+]], 0{{$}}
@@ -406,7 +406,7 @@ define void @load_constant_disjoint_offsets(i32 addrspace(1)* %out) {
   ret void
 }
 
-@bar = addrspace(3) global [4 x i64] zeroinitializer, align 4
+@bar = addrspace(3) global [4 x i64] undef, align 4
 
 ; SI-LABEL: @load_misaligned64_constant_offsets
 ; SI: v_mov_b32_e32 [[ZERO:v[0-9]+]], 0{{$}}
@@ -420,7 +420,7 @@ define void @load_misaligned64_constant_offsets(i64 addrspace(1)* %out) {
   ret void
 }
 
-@bar.large = addrspace(3) global [4096 x i64] zeroinitializer, align 4
+@bar.large = addrspace(3) global [4096 x i64] undef, align 4
 
 ; SI-LABEL: @load_misaligned64_constant_large_offsets
 ; SI-DAG: v_mov_b32_e32 [[BASE0:v[0-9]+]], 0x7ff8{{$}}
@@ -436,8 +436,8 @@ define void @load_misaligned64_constant_large_offsets(i64 addrspace(1)* %out) {
   ret void
 }
 
-@sgemm.lA = internal unnamed_addr addrspace(3) global [264 x float] zeroinitializer, align 4
-@sgemm.lB = internal unnamed_addr addrspace(3) global [776 x float] zeroinitializer, align 4
+@sgemm.lA = internal unnamed_addr addrspace(3) global [264 x float] undef, align 4
+@sgemm.lB = internal unnamed_addr addrspace(3) global [776 x float] undef, align 4
 
 define void @sgemm_inner_loop_read2_sequence(float addrspace(1)* %C, i32 %lda, i32 %ldb) #0 {
   %x.i = tail call i32 @llvm.r600.read.tgid.x() #1
index cbb8da63935539d76e03089f3767aec75891feea..3e98e590b00f0fb676b66f47402d7e242a8dc074 100644 (file)
@@ -1,7 +1,7 @@
 ; RUN: llc -march=r600 -mcpu=bonaire -verify-machineinstrs -mattr=+load-store-opt -enable-misched < %s | FileCheck -check-prefix=SI %s
 
-@lds = addrspace(3) global [512 x float] zeroinitializer, align 4
-@lds.f64 = addrspace(3) global [512 x double] zeroinitializer, align 8
+@lds = addrspace(3) global [512 x float] undef, align 4
+@lds.f64 = addrspace(3) global [512 x double] undef, align 8
 
 
 ; SI-LABEL: @simple_read2st64_f32_0_1
index 678435e2f4de982521c216bf6cd4d03b55068d07..1807fb552916b7a9c8b31a1d8e032fbeb26ee875 100644 (file)
@@ -1,7 +1,7 @@
 ; RUN: llc -march=r600 -mcpu=bonaire -verify-machineinstrs -mattr=+load-store-opt -enable-misched < %s | FileCheck -strict-whitespace -check-prefix=SI %s
 
-@lds = addrspace(3) global [512 x float] zeroinitializer, align 4
-@lds.f64 = addrspace(3) global [512 x double] zeroinitializer, align 8
+@lds = addrspace(3) global [512 x float] undef, align 4
+@lds.f64 = addrspace(3) global [512 x double] undef, align 8
 
 
 ; SI-LABEL: @simple_write2_one_val_f32
@@ -320,7 +320,7 @@ define void @simple_write2_two_val_f64(double addrspace(1)* %C, double addrspace
   ret void
 }
 
-@foo = addrspace(3) global [4 x i32] zeroinitializer, align 4
+@foo = addrspace(3) global [4 x i32] undef, align 4
 
 ; SI-LABEL: @store_constant_adjacent_offsets
 ; SI: v_mov_b32_e32 [[ZERO:v[0-9]+]], 0{{$}}
@@ -341,7 +341,7 @@ define void @store_constant_disjoint_offsets() {
   ret void
 }
 
-@bar = addrspace(3) global [4 x i64] zeroinitializer, align 4
+@bar = addrspace(3) global [4 x i64] undef, align 4
 
 ; SI-LABEL: @store_misaligned64_constant_offsets
 ; SI: v_mov_b32_e32 [[ZERO:v[0-9]+]], 0{{$}}
@@ -353,7 +353,7 @@ define void @store_misaligned64_constant_offsets() {
   ret void
 }
 
-@bar.large = addrspace(3) global [4096 x i64] zeroinitializer, align 4
+@bar.large = addrspace(3) global [4096 x i64] undef, align 4
 
 ; SI-LABEL: @store_misaligned64_constant_large_offsets
 ; SI-DAG: v_mov_b32_e32 [[BASE0:v[0-9]+]], 0x7ff8{{$}}
@@ -367,8 +367,8 @@ define void @store_misaligned64_constant_large_offsets() {
   ret void
 }
 
-@sgemm.lA = internal unnamed_addr addrspace(3) global [264 x float] zeroinitializer, align 4
-@sgemm.lB = internal unnamed_addr addrspace(3) global [776 x float] zeroinitializer, align 4
+@sgemm.lA = internal unnamed_addr addrspace(3) global [264 x float] undef, align 4
+@sgemm.lB = internal unnamed_addr addrspace(3) global [776 x float] undef, align 4
 
 define void @write2_sgemm_sequence(float addrspace(1)* %C, i32 %lda, i32 %ldb, float addrspace(1)* %in) #0 {
   %x.i = tail call i32 @llvm.r600.read.tgid.x() #1
index a2dc09aec29e653ecb28eed74a60e6e3b5cc1115..4cafb7c08dc9541e32354598bdb23fb1b5e93d4b 100644 (file)
@@ -1,7 +1,7 @@
 ; RUN: llc -march=r600 -mcpu=bonaire -verify-machineinstrs -mattr=+load-store-opt -enable-misched < %s | FileCheck -check-prefix=SI %s
 
 
-@lds = addrspace(3) global [512 x float] zeroinitializer, align 4
+@lds = addrspace(3) global [512 x float] undef, align 4
 
 
 ; SI-LABEL: @simple_write2st64_one_val_f32_0_1
diff --git a/test/CodeGen/R600/global-zero-initializer.ll b/test/CodeGen/R600/global-zero-initializer.ll
new file mode 100644 (file)
index 0000000..b69b061
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN: not llc -march=r600 -mcpu=SI < %s 2>&1 | FileCheck %s
+
+; CHECK: error: unsupported initializer for address space in load_init_global_global
+
+@lds = addrspace(1) global [256 x i32] zeroinitializer
+
+define void @load_init_global_global(i32 addrspace(1)* %out, i1 %p) {
+ %gep = getelementptr [256 x i32] addrspace(1)* @lds, i32 0, i32 10
+  %ld = load i32 addrspace(1)* %gep
+  store i32 %ld, i32 addrspace(1)* %out
+  ret void
+}
diff --git a/test/CodeGen/R600/lds-initializer.ll b/test/CodeGen/R600/lds-initializer.ll
new file mode 100644 (file)
index 0000000..91d5d12
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN: not llc -march=r600 -mcpu=SI < %s 2>&1 | FileCheck %s
+
+; CHECK: error: unsupported initializer for address space in load_init_lds_global
+
+@lds = addrspace(3) global [8 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8]
+
+define void @load_init_lds_global(i32 addrspace(1)* %out, i1 %p) {
+ %gep = getelementptr [8 x i32] addrspace(3)* @lds, i32 0, i32 10
+  %ld = load i32 addrspace(3)* %gep
+  store i32 %ld, i32 addrspace(1)* %out
+  ret void
+}
index a17951b872a0b3590b9a7851d34fb6ecc850e376..cda75b0e0cccb9abf302c9a6652406af2bd38589 100644 (file)
@@ -8,7 +8,7 @@
 ; CHECK-NOT: ALU clause
 ; CHECK: MOV * T{{[0-9]\.[XYZW]}}, OQAP
 
-@local_mem = internal unnamed_addr addrspace(3) global [2 x i32] [i32 1, i32 2], align 4
+@local_mem = internal unnamed_addr addrspace(3) global [2 x i32] undef, align 4
 
 define void @lds_input_queue(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %index) {
 entry:
index e9771d9d323dcf8c3244e78973d8a57ef2b60456..5287723ce191be49ad9371737dec6de37dd0d561 100644 (file)
@@ -6,7 +6,7 @@
 ; CHECK-LABEL: {{^}}test:
 ; CHECK: .long   166120
 ; CHECK-NEXT: .long   1
-@lds = internal unnamed_addr addrspace(3) global i32 zeroinitializer, align 4
+@lds = internal unnamed_addr addrspace(3) global i32 undef, align 4
 
 define void @test(i32 addrspace(1)* %out, i32 %cond) {
 entry:
diff --git a/test/CodeGen/R600/lds-zero-initializer.ll b/test/CodeGen/R600/lds-zero-initializer.ll
new file mode 100644 (file)
index 0000000..23912a9
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN: not llc -march=r600 -mcpu=SI < %s 2>&1 | FileCheck %s
+
+; CHECK: error: unsupported initializer for address space in load_zeroinit_lds_global
+
+@lds = addrspace(3) global [256 x i32] zeroinitializer
+
+define void @load_zeroinit_lds_global(i32 addrspace(1)* %out, i1 %p) {
+ %gep = getelementptr [256 x i32] addrspace(3)* @lds, i32 0, i32 10
+  %ld = load i32 addrspace(3)* %gep
+  store i32 %ld, i32 addrspace(1)* %out
+  ret void
+}
index c228c191766995b0b4f4610240fe69cfa852ae13..62d3063ef1eba679b24579962aba7479644e825c 100644 (file)
@@ -721,7 +721,7 @@ define void @load_i32_v2i32_local(<2 x i32> addrspace(1)* %out, i32 addrspace(3)
 }
 
 
-@lds = addrspace(3) global [512 x i32] zeroinitializer, align 4
+@lds = addrspace(3) global [512 x i32] undef, align 4
 
 ; On SI we need to make sure that the base offset is a register and not
 ; an immediate.
index 4121d60df252ef6c9a054b840f0d2f2949b871f4..88ef05d6839dbc822f449eb7f21591dc268043ab 100644 (file)
@@ -2,8 +2,8 @@
 ; RUN: llc < %s -march=r600 -mcpu=verde -verify-machineinstrs | FileCheck --check-prefix=SI-CHECK --check-prefix=SI %s
 ; RUN: llc < %s -march=r600 -mcpu=bonaire -verify-machineinstrs | FileCheck --check-prefix=SI-CHECK --check-prefix=CI %s
 
-@local_memory_two_objects.local_mem0 = internal unnamed_addr addrspace(3) global [4 x i32] zeroinitializer, align 4
-@local_memory_two_objects.local_mem1 = internal unnamed_addr addrspace(3) global [4 x i32] zeroinitializer, align 4
+@local_memory_two_objects.local_mem0 = internal unnamed_addr addrspace(3) global [4 x i32] undef, align 4
+@local_memory_two_objects.local_mem1 = internal unnamed_addr addrspace(3) global [4 x i32] undef, align 4
 
 ; EG-CHECK: {{^}}local_memory_two_objects:
 
index b7565277fd3eb56a12fd9a286e2d222d91db5c22..9b13cb2c4a0fcee5f25215fca19dbc08470f7ac6 100644 (file)
@@ -2,7 +2,7 @@
 ; RUN: llc -march=r600 -mcpu=verde -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
 ; RUN: llc -march=r600 -mcpu=bonaire -verify-machineinstrs < %s | FileCheck -check-prefix=CI -check-prefix=FUNC %s
 
-@local_memory.local_mem = internal unnamed_addr addrspace(3) global [128 x i32] zeroinitializer, align 4
+@local_memory.local_mem = internal unnamed_addr addrspace(3) global [128 x i32] undef, align 4
 
 ; FUNC-LABEL: {{^}}local_memory:
 
index fa912083d956d646836c07bf9ac0de5bbcf55e74..5346046df10311f4058f09b0dacc41c7ea356bbf 100644 (file)
@@ -1,6 +1,6 @@
 ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=FUNC -check-prefix=SI %s
 
-@ptr_load = addrspace(3) global i32 addrspace(2)* null, align 8
+@ptr_load = addrspace(3) global i32 addrspace(2)* undef, align 8
 
 ; Make sure when the load from %ptr2 is folded the chain isn't lost,
 ; resulting in losing the store to gptr
index e6dfc587eca752eedcf97193150c4f3611bd69b6..047cf252e78a1054d5780c0653d29ecb3bc025d5 100644 (file)
@@ -8,8 +8,8 @@
 
 declare i32 @llvm.r600.read.tidig.x() #1
 
-@lds0 = addrspace(3) global [512 x float] zeroinitializer, align 4
-@lds1 = addrspace(3) global [512 x float] zeroinitializer, align 4
+@lds0 = addrspace(3) global [512 x float] undef, align 4
+@lds1 = addrspace(3) global [512 x float] undef, align 4
 
 
 ; Make sure the (add tid, 2) << 2 gets folded into the ds's offset as (tid << 2) + 8
@@ -49,7 +49,7 @@ define void @load_shl_base_lds_1(float addrspace(1)* %out, i32 addrspace(1)* %ad
   ret void
 }
 
-@maxlds = addrspace(3) global [65536 x i8] zeroinitializer, align 4
+@maxlds = addrspace(3) global [65536 x i8] undef, align 4
 
 ; SI-LABEL: {{^}}load_shl_base_lds_max_offset
 ; SI: ds_read_u8 v{{[0-9]+}}, v{{[0-9]+}} offset:65535
@@ -100,7 +100,7 @@ define void @store_shl_base_lds_0(float addrspace(1)* %out, i32 addrspace(1)* %a
 ; --------------------------------------------------------------------------------
 ; Atomics.
 
-@lds2 = addrspace(3) global [512 x i32] zeroinitializer, align 4
+@lds2 = addrspace(3) global [512 x i32] undef, align 4
 
 ; define void @atomic_load_shl_base_lds_0(i32 addrspace(1)* %out, i32 addrspace(1)* %add_use) #0 {
 ;   %tid.x = tail call i32 @llvm.r600.read.tidig.x() #1