Selaa lähdekoodia

Fix crashes on Append/ConsumeStructuredBuffer of bools (#1985)

Our codegen for Append/Consume is unfortunate because it happens after initial codegen and we don't have access to lots of what would have made this easy. I've had to duplicate the register to memory conversion logic.
Tristan Labelle 6 vuotta sitten
vanhempi
commit
301e386f38

+ 23 - 5
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -3478,10 +3478,19 @@ static Function *CreateOpFunction(llvm::Module &M, Function *F,
       llvm::Type *idxTy = counterTy;
       llvm::Type *valTy = bAppend ?
           funcTy->getParamType(HLOperandIndex::kAppendValOpIndex):funcTy->getReturnType();
+
+      // Return type for subscript should be pointer type, hence in memory representation
       llvm::Type *subscriptTy = valTy;
-      if (!valTy->isPointerTy()) {
-        // Return type for subscript should be pointer type.
-        subscriptTy = llvm::PointerType::get(valTy, 0);
+      bool isBoolScalarOrVector = false;
+      if (!subscriptTy->isPointerTy()) {
+        if (subscriptTy->getScalarType()->isIntegerTy(1)) {
+          isBoolScalarOrVector = true;
+          llvm::Type *memReprType = llvm::IntegerType::get(subscriptTy->getContext(), 32);
+          subscriptTy = subscriptTy->isVectorTy()
+            ? llvm::VectorType::get(memReprType, subscriptTy->getVectorNumElements())
+            : memReprType;
+        }
+        subscriptTy = llvm::PointerType::get(subscriptTy, 0);
       }
 
       llvm::FunctionType *SubscriptFuncTy =
@@ -3514,8 +3523,14 @@ static Function *CreateOpFunction(llvm::Module &M, Function *F,
         if (valTy->isPointerTy()) {
           unsigned size = M.getDataLayout().getTypeAllocSize(subscript->getType()->getPointerElementType());
           Builder.CreateMemCpy(subscript, valArg, size, 1);
-        } else
-          Builder.CreateStore(valArg, subscript);
+        }
+        else {
+          Value *storedVal = valArg;
+          // Convert to memory representation
+          if (isBoolScalarOrVector)
+            storedVal = Builder.CreateZExt(storedVal, subscriptTy->getPointerElementType(), "frombool");
+          Builder.CreateStore(storedVal, subscript);
+        }
         Builder.CreateRetVoid();
       } else {
         // return Buf[counter];
@@ -3523,6 +3538,9 @@ static Function *CreateOpFunction(llvm::Module &M, Function *F,
           Builder.CreateRet(subscript);
         else {
           Value *retVal = Builder.CreateLoad(subscript);
+          // Convert to register representation
+          if (isBoolScalarOrVector)
+            retVal = Builder.CreateICmpNE(retVal, Constant::getNullValue(retVal->getType()), "tobool");
           Builder.CreateRet(retVal);
         }
       }

+ 27 - 0
tools/clang/test/CodeGenHLSL/declarations/bool_representation/buffer_append_consume.hlsl

@@ -0,0 +1,27 @@
+// RUN: %dxc -E main -T vs_6_2 %s | FileCheck %s
+
+// Check that bool register to memory representation conversions happen
+// when using AppendStructuredBuffer/ConsumeStructuredBuffer,
+// since this is handled by special-purpose code.
+// Regression test for GitHub #1882, where this was crashing.
+
+ConsumeStructuredBuffer<bool> boolIn;
+ConsumeStructuredBuffer<bool2> boolVecIn;
+AppendStructuredBuffer<bool> boolOut;
+AppendStructuredBuffer<bool2> boolVecOut;
+void main()
+{
+    // CHECK: rawBufferLoad
+    // CHECK: icmp ne i32 %{{.*}}, 0
+    // CHECK: zext i1 %{{.*}} to i32
+    // CHECK: rawBufferStore
+    boolOut.Append(boolIn.Consume());
+    
+    // CHECK: rawBufferLoad
+    // CHECK: icmp ne i32 %{{.*}}, 0
+    // CHECK: icmp ne i32 %{{.*}}, 0
+    // CHECK: zext i1 %{{.*}} to i32
+    // CHECK: zext i1 %{{.*}} to i32
+    // CHECK: rawBufferStore
+    boolVecOut.Append(boolVecIn.Consume());
+}