From 27a6038aa07735ae6f75030247f9dfa900e63d06 Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Tue, 19 Jan 2021 11:09:36 +0100 Subject: [PATCH 1/2] Only construct legal int types during alloc opt. When promoting heap to stack allocations, make sure we only emit legal integer allocas by checking with the module's datalayout. X86 doesn't seem to care, but back-ends like SPIR-V don't know how to handle arbitrarily-sized integers. Fixes JuliaGPU/oneAPI.jl#55 --- src/llvm-alloc-opt.cpp | 11 +++++++++-- test/llvmpasses/alloc-opt2.jl | 20 +++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/llvm-alloc-opt.cpp b/src/llvm-alloc-opt.cpp index c6d9dce9b8548..381380372db40 100644 --- a/src/llvm-alloc-opt.cpp +++ b/src/llvm-alloc-opt.cpp @@ -936,7 +936,12 @@ void Optimizer::moveToStack(CallInst *orig_inst, size_t sz, bool has_ref) ptr = cast(prolog_builder.CreateBitCast(buff, pass.T_pint8)); } else { - buff = prolog_builder.CreateAlloca(Type::getIntNTy(pass.getLLVMContext(), sz * 8)); + Type *buffty; + if (pass.DL->isLegalInteger(sz * 8)) + buffty = Type::getIntNTy(pass.getLLVMContext(), sz * 8); + else + buffty = ArrayType::get(Type::getInt8Ty(pass.getLLVMContext()), sz); + buff = prolog_builder.CreateAlloca(buffty); buff->setAlignment(Align(align)); ptr = cast(prolog_builder.CreateBitCast(buff, pass.T_pint8)); } @@ -1193,8 +1198,10 @@ void Optimizer::splitOnStack(CallInst *orig_inst) else if (field.elty && !field.multiloc) { allocty = field.elty; } - else { + else if (pass.DL->isLegalInteger(field.size * 8)) { allocty = Type::getIntNTy(pass.getLLVMContext(), field.size * 8); + } else { + allocty = ArrayType::get(Type::getInt8Ty(pass.getLLVMContext()), field.size); } slot.slot = prolog_builder.CreateAlloca(allocty); insertLifetime(prolog_builder.CreateBitCast(slot.slot, pass.T_pint8), diff --git a/test/llvmpasses/alloc-opt2.jl b/test/llvmpasses/alloc-opt2.jl index 00a4394352fbf..8a3f5aa941feb 100644 --- a/test/llvmpasses/alloc-opt2.jl +++ b/test/llvmpasses/alloc-opt2.jl @@ -79,12 +79,30 @@ L3: """) # CHECK-LABEL: }{{$}} +# CHECK-LABEL: @legal_int_types +# CHECK: alloca [12 x i8] +# CHECK-NOT: alloca i96 +# CHECK: ret void +println(""" +define void @legal_int_types() { + %ptls = call {}*** @julia.ptls_states() + %ptls_i8 = bitcast {}*** %ptls to i8* + %var1 = call {} addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, $isz 12, {} addrspace(10)* @tag) + %var2 = addrspacecast {} addrspace(10)* %var1 to {} addrspace(11)* + %var3 = call {}* @julia.pointer_from_objref({} addrspace(11)* %var2) + ret void +} +""") +# CHECK-LABEL: }{{$}} + + + println(""" declare void @external_function() declare {} addrspace(10)* @external_function2() declare {}*** @julia.ptls_states() declare noalias {} addrspace(10)* @julia.gc_alloc_obj(i8*, $isz, {} addrspace(10)*) -declare i64 @julia.pointer_from_objref({} addrspace(11)*) +declare {}* @julia.pointer_from_objref({} addrspace(11)*) declare void @llvm.memcpy.p11i8.p0i8.i64(i8 addrspace(11)* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) declare token @llvm.julia.gc_preserve_begin(...) declare void @llvm.julia.gc_preserve_end(token) From 543ac5ffb480467b01fb2be898df5ce9a97de6a1 Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Tue, 19 Jan 2021 11:29:24 +0100 Subject: [PATCH 2/2] Adapt the alloc-opt tests. --- test/llvmpasses/alloc-opt.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/llvmpasses/alloc-opt.jl b/test/llvmpasses/alloc-opt.jl index dd1ff78151f95..e48a85641257b 100644 --- a/test/llvmpasses/alloc-opt.jl +++ b/test/llvmpasses/alloc-opt.jl @@ -5,6 +5,8 @@ isz = sizeof(UInt) == 8 ? "i64" : "i32" println(""" +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" + @tag = external addrspace(10) global {} """) @@ -167,7 +169,7 @@ define void @object_field({} addrspace(10)* %field) { # CHECK-LABEL: }{{$}} # CHECK-LABEL: @memcpy_opt -# CHECK: alloca i128, align 16 +# CHECK: alloca [16 x i8], align 16 # CHECK: call {}*** @julia.ptls_states() # CHECK-NOT: @julia.gc_alloc_obj # CHECK-NOT: @jl_gc_pool_alloc