(original) (raw)

Solved by using alloca i8\*, i32 2 which the system seems happy enough with, and bitcasting to the actual type for rest of the code after llvm.gcroot.

Not entirely sure if this is a terrible workaround or exactly the way gcroot is supposed to be used...


On Wed, Nov 1, 2017 at 11:59 AM, Nikodemus Siivola <nikodemus@random-state.net> wrote:
I'm allocating { i8\*, i32 } on the stack, and would like to add this as a GC root, but I'm having trouble figuring this out.

This works as expected:

declare void @llvm.gcroot(i8\*\* %ptrloc, i8\* %metadata)

define i8\* @bar(i8\* %x) gc "shadow-stack" {
entry:
%objptr = alloca i8\*
call void @llvm.gcroot(i8\*\* %objptr, i8\* null)
store i8\* %x, i8\*\* %objptr
%v = load i8\*, i8\*\* %objptr
ret i8\* %v
}

However, when I have this:

define { i8\*, i32 } @foo({ i8\*, i32 } %x) gc "shadow-stack" {
entry:
%objptr = alloca { i8\*, i32 }
%rootptr = bitcast { i8\*, i32 }\* %objptr to i8\*\*
call void @llvm.gcroot(i8\*\* %rootptr, i8\* null)
store { i8\*, i32 } %x, { i8\*, i32 }\* %objptr
%v = load { i8\*, i32 }, { i8\*, i32 }\* %objptr
ret { i8\*, i32 } %v
}

llc says: llvm.gcroot parameter #1 must either be a pointer alloca, or argument #2 must be a non-null constant.
call void @llvm.gcroot(i8\*\* %rootptr, i8\* null)

...and if I do as it asks and add a metadata then I get a crash:

@info = constant i8 1

define { i8\*, i32 } @quux({ i8\*, i32 } %x) gc "shadow-stack" {
entry:
%objptr = alloca { i8\*, i32 }
%rootptr = bitcast { i8\*, i32 }\* %objptr to i8\*\*
call void @llvm.gcroot(i8\*\* %rootptr, i8\* @info)
store { i8\*, i32 } %x, { i8\*, i32 }\* %objptr
%v = load { i8\*, i32 }, { i8\*, i32 }\* %objptr
ret { i8\*, i32 } %v
}

leads llc into this:

Assertion failed: isa(Val) && "cast() argument of incompatible type!", file C:\\Users\\nikod\\src\\llvm\\include\\llvm/Support/Casting.h, line 236
Wrote crash dump file "C:\\Users\\nikod\\AppData\\Local\\Temp\\llc.exe-7b1546.dmp"
#0 0x01a26809 HandleAbort c:\\users\\nikod\\src\\llvm\\lib\\support\\windows\\signals.inc:405:0
#1 0x75804188 (C:\\WINDOWS\\System32\\ucrtbase.dll+0xa4188)
#2 0x75805422 (C:\\WINDOWS\\System32\\ucrtbase.dll+0xa5422)
#3 0x75806dc5 (C:\\WINDOWS\\System32\\ucrtbase.dll+0xa6dc5)
#4 0x75806ce8 (C:\\WINDOWS\\System32\\ucrtbase.dll+0xa6ce8)
#5 0x7580618b (C:\\WINDOWS\\System32\\ucrtbase.dll+0xa618b)
#6 0x75806e26 (C:\\WINDOWS\\System32\\ucrtbase.dll+0xa6e26)
#7 0x013786a6 InsertRootInitializers c:\\users\\nikod\\src\\llvm\\lib\\codegen\\gcrootlowering.cpp:172:0
#8 0x01378d97 \`anonymous namespace'::LowerIntrinsics::PerformDefaultLowering c:\\users\\nikod\\src\\llvm\\lib\\codegen\\gcrootlowering.cpp:249:0
#9 0x01379986 \`anonymous namespace'::LowerIntrinsics::runOnFunction c:\\users\\nikod\\src\\llvm\\lib\\codegen\\gcrootlowering.cpp:195:0
#10 0x016a343c llvm::FPPassManager::runOnFunction(class llvm::Function &) c:\\users\\nikod\\src\\llvm\\lib\\ir\\legacypassmanager.cpp:1513:0
#11 0x016a35e4 llvm::FPPassManager::runOnModule(class llvm::Module &) c:\\users\\nikod\\src\\llvm\\lib\\ir\\legacypassmanager.cpp:1533:0
#12 0x016a382c \`anonymous namespace'::MPPassManager::runOnModule c:\\users\\nikod\\src\\llvm\\lib\\ir\\legacypassmanager.cpp:1590:0
#13 0x016a2e0e llvm::legacy::PassManagerImpl::run(class llvm::Module &) c:\\users\\nikod\\src\\llvm\\lib\\ir\\legacypassmanager.cpp:1693:0
#14 0x01000a62 compileModule c:\\users\\nikod\\src\\llvm\\tools\\llc\\llc.cpp:534:0
#15 0x010059ca main c:\\users\\nikod\\src\\llvm\\tools\\llc\\llc.cpp:289:0
#16 0x01be99e9 \_scrt\_common\_main\_seh f:\\dd\\vctools\\crt\\vcstartup\\src\\startup\\exe\_common.inl:253:0
#17 0x77178744 (C:\\WINDOWS\\System32\\KERNEL32.DLL+0x18744)
#18 0x7737582d (C:\\WINDOWS\\SYSTEM32\\ntdll.dll+0x6582d)
#19 0x773757fd (C:\\WINDOWS\\SYSTEM32\\ntdll.dll+0x657fd)

(This is the same assertion failure that my full code produces, and which lead me to trying out things with minimal case and llc.)

What I can see in the debugger isn't immediately illuminating. Any clues? Am I missing the obvious here?

This is:

LLVM version 4.0.1
DEBUG build with assertions.
Default target: i686-pc-windows-msvc
Host CPU: skylake

Cheers,

-- nikodemus