From 7f2ad40221769fe416911e8e56622912da1eb2e0 Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Tue, 22 Aug 2023 17:00:40 -0700 Subject: [PATCH] fix: Handle mixed string casting that plagues optix codegen The string situation is still a bit tricky on the OptiX side. There's a full overhaul of that coming separately as we continue to shift to an all-ustringhash world. But in the mean time, we were getting some testsuite failures that were because of a mismatch between times we think of a gpu-side ustring as a char* and when it's a uint64. IN FACT, they are always the hashes, but we backed ourselves into a corner where sometimes that 64 bit pattern is passed around as a pointer, ugh. This small patch attempts to catch this case and just do the appropriate cast to compensate. It's a band-aid, a more comprehensive fix is coming, as I said. This gets us down to just ONE filing optix test case, which I will tackle separately. Signed-off-by: Larry Gritz --- src/include/OSL/llvm_util.h | 4 ++++ src/liboslexec/backendllvm.cpp | 7 +++++++ src/liboslexec/llvm_util.cpp | 9 +++++++++ 3 files changed, 20 insertions(+) diff --git a/src/include/OSL/llvm_util.h b/src/include/OSL/llvm_util.h index b42eee776..37bf595bf 100644 --- a/src/include/OSL/llvm_util.h +++ b/src/include/OSL/llvm_util.h @@ -762,6 +762,10 @@ class OSLEXECPUBLIC LLVM_Util { /// return the llvm::Value of the new pointer. llvm::Value* int_to_ptr_cast(llvm::Value* val); + /// Cast the pointer specified by ptr to an int64, return the llvm::Value + /// of the new value. + llvm::Value* ptr_to_int64_cast(llvm::Value* ptr); + /// Cast the pointer variable specified by val to a pointer of type /// void* return the llvm::Value of the new pointer. llvm::Value* void_ptr(llvm::Value* val, const std::string& llname = {}); diff --git a/src/liboslexec/backendllvm.cpp b/src/liboslexec/backendllvm.cpp index aa82fc9e7..f130adb63 100644 --- a/src/liboslexec/backendllvm.cpp +++ b/src/liboslexec/backendllvm.cpp @@ -665,6 +665,13 @@ BackendLLVM::llvm_store_value(llvm::Value* new_val, llvm::Value* dst_ptr, dst_ptr = ll.GEP(dst_ptr, 0, component); // Finally, store the value. + if (t == TypeString && dst_ptr->getType() == ll.type_int64_ptr() + && new_val->getType() == ll.type_char_ptr()) { + // Special case: we are still ickily storing strings sometimes as a + // char* and sometimes as a uint64. Do a little sneaky conversion + // here. + new_val = ll.ptr_to_int64_cast(new_val); + } ll.op_store(new_val, dst_ptr); return true; } diff --git a/src/liboslexec/llvm_util.cpp b/src/liboslexec/llvm_util.cpp index d344655b4..9ca219005 100644 --- a/src/liboslexec/llvm_util.cpp +++ b/src/liboslexec/llvm_util.cpp @@ -3429,6 +3429,14 @@ LLVM_Util::int_to_ptr_cast(llvm::Value* val) +llvm::Value* +LLVM_Util::ptr_to_int64_cast(llvm::Value* ptr) +{ + return builder().CreatePtrToInt(ptr, type_int64()); +} + + + llvm::Value* LLVM_Util::void_ptr(llvm::Value* val, const std::string& llname) { @@ -5216,6 +5224,7 @@ LLVM_Util::op_store(llvm::Value* val, llvm::Value* ptr) std::cerr << "op_store val->getType()=" << std::flush; val->getType()->print(llvm::errs()); std::cerr << std::endl; + // OSL_ASSERT(0); } if (m_mask_stack.empty() || val->getType()->isVectorTy() == false || (!is_masking_required())) {