diff options
Diffstat (limited to 'clang/lib/CodeGen/CGHLSLBuiltins.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGHLSLBuiltins.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index 12d9a98915ce..5ae3fed099cd 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -404,6 +404,49 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, RetTy, CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(), ArrayRef<Value *>{HandleOp, IndexOp}); } + case Builtin::BI__builtin_hlsl_resource_load_with_status: { + Value *HandleOp = EmitScalarExpr(E->getArg(0)); + Value *IndexOp = EmitScalarExpr(E->getArg(1)); + + // Get the *address* of the status argument to write to it by reference + LValue StatusLVal = EmitLValue(E->getArg(2)); + Address StatusAddr = StatusLVal.getAddress(); + + QualType HandleTy = E->getArg(0)->getType(); + const HLSLAttributedResourceType *RT = + HandleTy->getAs<HLSLAttributedResourceType>(); + assert(CGM.getTarget().getTriple().getArch() == llvm::Triple::dxil && + "Only DXIL currently implements load with status"); + + Intrinsic::ID IntrID = RT->getAttrs().RawBuffer + ? llvm::Intrinsic::dx_resource_load_rawbuffer + : llvm::Intrinsic::dx_resource_load_typedbuffer; + + llvm::Type *DataTy = ConvertType(E->getType()); + llvm::Type *RetTy = llvm::StructType::get(Builder.getContext(), + {DataTy, Builder.getInt1Ty()}); + + SmallVector<Value *, 3> Args; + Args.push_back(HandleOp); + Args.push_back(IndexOp); + + if (RT->getAttrs().RawBuffer) { + Value *Offset = Builder.getInt32(0); + Args.push_back(Offset); + } + + // The load intrinsics give us a (T value, i1 status) pair - + // shepherd these into the return value and out reference respectively. + Value *ResRet = + Builder.CreateIntrinsic(RetTy, IntrID, Args, {}, "ld.struct"); + Value *LoadedValue = Builder.CreateExtractValue(ResRet, {0}, "ld.value"); + Value *StatusBit = Builder.CreateExtractValue(ResRet, {1}, "ld.status"); + Value *ExtendedStatus = + Builder.CreateZExt(StatusBit, Builder.getInt32Ty(), "ld.status.ext"); + Builder.CreateStore(ExtendedStatus, StatusAddr); + + return LoadedValue; + } case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: { llvm::Type *HandleTy = CGM.getTypes().ConvertType(E->getType()); return llvm::PoisonValue::get(HandleTy); |
