[clang] [HLSL] Implement HLSL Flat casting (excluding splat cases) (PR #118842)
Chris B via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 14 13:47:22 PST 2025
================
@@ -491,6 +491,81 @@ static bool isTrivialFiller(Expr *E) {
return false;
}
+// emit a flat cast where the RHS is a scalar, including vector
+static void EmitHLSLScalarFlatCast(CodeGenFunction &CGF, Address DestVal,
+ QualType DestTy, llvm::Value *SrcVal,
+ QualType SrcTy, SourceLocation Loc) {
+ // Flatten our destination
+ SmallVector<QualType, 16> DestTypes; // Flattened type
+ SmallVector<std::pair<Address, llvm::Value *>, 16> StoreGEPList;
+ // ^^ Flattened accesses to DestVal we want to store into
+ CGF.FlattenAccessAndType(DestVal, DestTy, StoreGEPList, DestTypes);
+
+ if (const VectorType *VT = SrcTy->getAs<VectorType>()) {
+ SrcTy = VT->getElementType();
+ assert(StoreGEPList.size() <= VT->getNumElements() &&
+ "Cannot perform HLSL flat cast when vector source \
+ object has less elements than flattened destination \
+ object.");
+ for (unsigned i = 0; i < StoreGEPList.size(); i++) {
+ llvm::Value *Load =
+ CGF.Builder.CreateExtractElement(SrcVal, i, "vec.load");
+ llvm::Value *Cast =
+ CGF.EmitScalarConversion(Load, SrcTy, DestTypes[i], Loc);
+
+ // store back
+ llvm::Value *Idx = StoreGEPList[i].second;
+ if (Idx) {
+ llvm::Value *V =
+ CGF.Builder.CreateLoad(StoreGEPList[i].first, "load.for.insert");
+ Cast = CGF.Builder.CreateInsertElement(V, Cast, Idx);
+ }
+ CGF.Builder.CreateStore(Cast, StoreGEPList[i].first);
+ }
+ return;
+ }
+ llvm_unreachable("HLSL Flat cast doesn't handle splatting.");
----------------
llvm-beanz wrote:
If this function is only ever supposed to be called where the source type is a vector, I'd rewrite this to have an assert on that precondition rather than a branch with an unreachable.
https://github.com/llvm/llvm-project/pull/118842
More information about the cfe-commits
mailing list