numba / llvmlite

A lightweight LLVM python binding for writing JIT compilers
https://llvmlite.pydata.org/
BSD 2-Clause "Simplified" License
1.92k stars 316 forks source link

`getelementptr` using a vector of pointers #756

Open siboehm opened 3 years ago

siboehm commented 3 years ago

LLVM allows using getelementptr with Vector indices, from LLVM 10 LangRef:

; Add distinct offsets to the same pointer:
;   A[i] = ptr + offsets[i]*sizeof(i8)
%A = getelementptr i8, i8* %ptr, <4 x i64> %offsets

However llvmlite doesn't seem to allow this, see code from PointerType: https://github.com/numba/llvmlite/blob/09df344ef758174949d582a2c85f2a2d0490e403/llvmlite/ir/types.py#L137-L143

Example

from llvmlite import ir

int_t = ir.IntType(64)
double_t = ir.DoubleType()
double_ptr_t = ir.PointerType(double_t)
module = ir.Module("mod")
func = ir.Function(module, ir.FunctionType(double_t, (double_ptr_t,)), "fn")

block = func.append_basic_block("entry")
builder = ir.IRBuilder(block)
ptr_vec = builder.gep(func.args[0], (ir.Constant(ir.VectorType(int_t, 1), [0]),))
ptr = builder.extract_element(ptr_vec, ir.Constant(int_t, 0))
builder.ret(builder.load(ptr))

print(module)

Should result in

; ModuleID = "mod"
target triple = "unknown-unknown-unknown"
target datalayout = ""

define double @"fn"(double* %".1") 
{
entry:
  %".3" = getelementptr double, double* %".1", <1 x i64> <i64 0>
  %".4" = extractelement <1 x double*> %".3", i32 0
  %".5" = load double, double* %".4"
  ret double %".5"
}

this IR is valid (opt doesn't complain)

but instead I get

Traceback (most recent call last):
  File "/home/simon/Documents/Projects/lleaves/issue.py", line 11, in <module>
    ptr_vec = builder.gep(func.args[0], (ir.Constant(ir.VectorType(int_t, 1), [0]),))
  File "/home/simon/.local/lib/python3.9/site-packages/llvmlite/ir/builder.py", line 924, in gep
    instr = instructions.GEPInstr(self.block, ptr, indices,
  File "/home/simon/.local/lib/python3.9/site-packages/llvmlite/ir/instructions.py", line 498, in __init__
    lasttyp, typ = typ, typ.gep(i)
  File "/home/simon/.local/lib/python3.9/site-packages/llvmlite/ir/types.py", line 142, in gep
    raise TypeError(i.type)
TypeError: <1 x i64>
gmarkall commented 3 years ago

Thanks for bringing this up - I've labelled it as a feature request.

Would you be interested in looking into contributing support for passing vectors of pointers to GEP in a PR? If you are, and you need any pointers / assistance along the way, please do post back here or drop into the numba-dev Gitter channel: https://gitter.im/numba/numba-dev