Skip to content

Commit ac602d8

Browse files
authored
[DirectX] Disallow ElementIndex for raw buffer accesses (#173320)
Raw (as in ByteAddress) buffer accesses in DXIL must specify ElementIndex as undef, and Structured buffer accesses must specify a value. Ensure that we do this correctly in DXILResourceAccess, and enforce that the operations are valid in DXILOpLowering. Fixes #173316
1 parent 7bad288 commit ac602d8

File tree

10 files changed

+177
-37
lines changed

10 files changed

+177
-37
lines changed

llvm/docs/DirectX/DXILResources.rst

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,11 @@ which matches DXIL. Unlike in the `RawBufferLoad`_ operation, we do not need
402402
arguments for the mask/type size and alignment, since we can calculate these
403403
from the return type of the load during lowering.
404404

405+
Note that RawBuffer loads represent either "structured" accesses, as in HLSL's
406+
StructuredBuffer<T>, or a "raw" access, as in HLSL's "ByteAddressBuffer". The
407+
`%offset` parameter is only used for structured accesses, and *must* be
408+
`poison` for raw accesses.
409+
405410
.. _RawBufferLoad: https://github.com/microsoft/DirectXShaderCompiler/blob/main/docs/DXIL.rst#rawbufferload
406411

407412
.. list-table:: ``@llvm.dx.resource.load.rawbuffer``
@@ -442,7 +447,7 @@ Examples:
442447
@llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_i8_0_0_0t(
443448
target("dx.RawBuffer", i8, 0, 0, 0) %buffer,
444449
i32 %byte_offset,
445-
i32 0)
450+
i32 poison)
446451
447452
; float4
448453
%ret = call {<4 x float>, i1}
@@ -454,7 +459,7 @@ Examples:
454459
@llvm.dx.resource.load.rawbuffer.v4f32.tdx.RawBuffer_i8_0_0_0t(
455460
target("dx.RawBuffer", i8, 0, 0, 0) %buffer,
456461
i32 %byte_offset,
457-
i32 0)
462+
i32 poison)
458463
459464
; struct S0 { float4 f; int4 i; };
460465
%ret = call {<4 x float>, i1}
@@ -488,7 +493,7 @@ Examples:
488493
@llvm.dx.resource.load.rawbuffer.v4i64.tdx.RawBuffer_i8_0_0t(
489494
target("dx.RawBuffer", i8, 0, 0, 0) %buffer,
490495
i32 %byte_offset,
491-
i32 0)
496+
i32 poison)
492497
493498
Stores
494499
------

llvm/lib/Target/DirectX/DXILOpLowering.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,24 @@ class OpLowerer {
272272
return false;
273273
}
274274

275+
Error validateRawBufferElementIndex(Value *Resource, Value *ElementIndex) {
276+
bool IsStructured =
277+
cast<RawBufferExtType>(Resource->getType())->isStructured();
278+
bool IsPoison = isa<PoisonValue>(ElementIndex);
279+
280+
if (IsStructured && IsPoison)
281+
return make_error<StringError>(
282+
"Element index of structured buffer may not be poison",
283+
inconvertibleErrorCode());
284+
285+
if (!IsStructured && !IsPoison)
286+
return make_error<StringError>(
287+
"Element index of raw buffer must be poison",
288+
inconvertibleErrorCode());
289+
290+
return Error::success();
291+
}
292+
275293
[[nodiscard]] bool lowerToCreateHandle(Function &F) {
276294
IRBuilder<> &IRB = OpBuilder.getIRB();
277295
Type *Int8Ty = IRB.getInt8Ty();
@@ -560,6 +578,11 @@ class OpLowerer {
560578
Value *Align =
561579
ConstantInt::get(Int32Ty, DL.getPrefTypeAlign(ScalarTy).value());
562580

581+
if (Error E = validateRawBufferElementIndex(CI->getOperand(0), Index1))
582+
return E;
583+
if (isa<PoisonValue>(Index1))
584+
Index1 = UndefValue::get(Index1->getType());
585+
563586
Expected<CallInst *> OpCall =
564587
MMDI.DXILVersion >= VersionTuple(1, 2)
565588
? OpBuilder.tryCreateOp(OpCode::RawBufferLoad,
@@ -671,6 +694,13 @@ class OpLowerer {
671694
Value *Index0 = CI->getArgOperand(1);
672695
Value *Index1 = IsRaw ? CI->getArgOperand(2) : UndefValue::get(Int32Ty);
673696

697+
if (IsRaw) {
698+
if (Error E = validateRawBufferElementIndex(CI->getOperand(0), Index1))
699+
return E;
700+
if (isa<PoisonValue>(Index1))
701+
Index1 = UndefValue::get(Index1->getType());
702+
}
703+
674704
Value *Data = CI->getArgOperand(IsRaw ? 3 : 2);
675705
Type *DataTy = Data->getType();
676706
Type *ScalarTy = DataTy->getScalarType();

llvm/lib/Target/DirectX/DXILResourceAccess.cpp

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,19 +120,33 @@ static void createTypedBufferStore(IntrinsicInst *II, StoreInst *SI,
120120
SI->replaceAllUsesWith(Inst);
121121
}
122122

123-
static void createRawStore(IntrinsicInst *II, StoreInst *SI) {
123+
static void createRawStore(IntrinsicInst *II, StoreInst *SI,
124+
dxil::ResourceTypeInfo &RTI) {
124125
const DataLayout &DL = SI->getDataLayout();
125126
IRBuilder<> Builder(SI);
126127

127128
Value *V = SI->getValueOperand();
129+
assert(!V->getType()->isAggregateType() &&
130+
"Resource store should be scalar or vector type");
131+
132+
Value *Index = II->getOperand(1);
128133
// The offset for the rawbuffer load and store ops is always in bytes.
129134
uint64_t AccessSize = 1;
130135
Value *Offset =
131136
traverseGEPOffsets(DL, Builder, SI->getPointerOperand(), AccessSize);
132-
// TODO: break up larger types
133-
auto *Inst = Builder.CreateIntrinsic(
134-
Builder.getVoidTy(), Intrinsic::dx_resource_store_rawbuffer,
135-
{II->getOperand(0), II->getOperand(1), Offset, V});
137+
138+
// For raw buffer (ie, HLSL's ByteAddressBuffer), we need to fold the access
139+
// entirely into the index.
140+
if (!RTI.isStruct()) {
141+
auto *ConstantOffset = dyn_cast<ConstantInt>(Offset);
142+
if (!ConstantOffset || !ConstantOffset->isZero())
143+
Index = Builder.CreateAdd(Index, Offset);
144+
Offset = llvm::PoisonValue::get(Builder.getInt32Ty());
145+
}
146+
147+
auto *Inst = Builder.CreateIntrinsic(Builder.getVoidTy(),
148+
Intrinsic::dx_resource_store_rawbuffer,
149+
{II->getOperand(0), Index, Offset, V});
136150
SI->replaceAllUsesWith(Inst);
137151
}
138152

@@ -143,7 +157,7 @@ static void createStoreIntrinsic(IntrinsicInst *II, StoreInst *SI,
143157
return createTypedBufferStore(II, SI, RTI);
144158
case dxil::ResourceKind::RawBuffer:
145159
case dxil::ResourceKind::StructuredBuffer:
146-
return createRawStore(II, SI);
160+
return createRawStore(II, SI, RTI);
147161
case dxil::ResourceKind::Texture1D:
148162
case dxil::ResourceKind::Texture2D:
149163
case dxil::ResourceKind::Texture2DMS:
@@ -198,20 +212,33 @@ static void createTypedBufferLoad(IntrinsicInst *II, LoadInst *LI,
198212
LI->replaceAllUsesWith(V);
199213
}
200214

201-
static void createRawLoad(IntrinsicInst *II, LoadInst *LI) {
215+
static void createRawLoad(IntrinsicInst *II, LoadInst *LI,
216+
dxil::ResourceTypeInfo &RTI) {
202217
const DataLayout &DL = LI->getDataLayout();
203218
IRBuilder<> Builder(LI);
204219

205-
// TODO: break up larger types
206220
Type *LoadType = StructType::get(LI->getType(), Builder.getInt1Ty());
221+
assert(!LI->getType()->isAggregateType() &&
222+
"Resource load should be scalar or vector type");
207223

224+
Value *Index = II->getOperand(1);
208225
// The offset for the rawbuffer load and store ops is always in bytes.
209226
uint64_t AccessSize = 1;
210227
Value *Offset =
211228
traverseGEPOffsets(DL, Builder, LI->getPointerOperand(), AccessSize);
229+
230+
// For raw buffer (ie, HLSL's ByteAddressBuffer), we need to fold the access
231+
// entirely into the index.
232+
if (!RTI.isStruct()) {
233+
auto *ConstantOffset = dyn_cast<ConstantInt>(Offset);
234+
if (!ConstantOffset || !ConstantOffset->isZero())
235+
Index = Builder.CreateAdd(Index, Offset);
236+
Offset = llvm::PoisonValue::get(Builder.getInt32Ty());
237+
}
238+
212239
Value *V =
213240
Builder.CreateIntrinsic(LoadType, Intrinsic::dx_resource_load_rawbuffer,
214-
{II->getOperand(0), II->getOperand(1), Offset});
241+
{II->getOperand(0), Index, Offset});
215242
V = Builder.CreateExtractValue(V, {0});
216243

217244
LI->replaceAllUsesWith(V);
@@ -367,7 +394,7 @@ static void createLoadIntrinsic(IntrinsicInst *II, LoadInst *LI,
367394
return createTypedBufferLoad(II, LI, RTI);
368395
case dxil::ResourceKind::RawBuffer:
369396
case dxil::ResourceKind::StructuredBuffer:
370-
return createRawLoad(II, LI);
397+
return createRawLoad(II, LI, RTI);
371398
case dxil::ResourceKind::CBuffer:
372399
return createCBufferLoad(II, LI, RTI);
373400
case dxil::ResourceKind::Texture1D:

llvm/test/CodeGen/DirectX/BufferLoad-sm61.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ define void @loadv4f32_byte(i32 %offset) {
2525
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0_0(
2626
i32 0, i32 0, i32 1, i32 0, ptr null)
2727

28-
; CHECK: [[DATA:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle %{{.*}}, i32 %offset, i32 0)
28+
; CHECK: [[DATA:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle %{{.*}}, i32 %offset, i32 undef)
2929
%load = call {<4 x float>, i1}
3030
@llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_i8_0_0_0t(
3131
target("dx.RawBuffer", i8, 0, 0, 0) %buffer,
3232
i32 %offset,
33-
i32 0)
33+
i32 poison)
3434

3535
ret void
3636
}

llvm/test/CodeGen/DirectX/BufferStore-sm61.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ define void @storef32_byte(i32 %offset, float %data) {
2323
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0_0(
2424
i32 0, i32 0, i32 1, i32 0, ptr null)
2525

26-
; CHECK: call void @dx.op.bufferStore.f32(i32 69, %dx.types.Handle %{{.*}}, i32 %offset, i32 0, float %data, float undef, float undef, float undef, i8 1)
26+
; CHECK: call void @dx.op.bufferStore.f32(i32 69, %dx.types.Handle %{{.*}}, i32 %offset, i32 undef, float %data, float undef, float undef, float undef, i8 1)
2727
call void @llvm.dx.resource.store.rawbuffer.f32(
2828
target("dx.RawBuffer", i8, 1, 0, 0) %buffer,
29-
i32 %offset, i32 0, float %data)
29+
i32 %offset, i32 poison, float %data)
3030

3131
ret void
3232
}
@@ -59,10 +59,10 @@ define void @storev4f32_byte(i32 %offset, <4 x float> %data) {
5959
; CHECK: [[DATA1:%.*]] = extractelement <4 x float> %data, i32 1
6060
; CHECK: [[DATA2:%.*]] = extractelement <4 x float> %data, i32 2
6161
; CHECK: [[DATA3:%.*]] = extractelement <4 x float> %data, i32 3
62-
; CHECK: call void @dx.op.bufferStore.f32(i32 69, %dx.types.Handle %{{.*}}, i32 %offset, i32 0, float [[DATA0]], float [[DATA1]], float [[DATA2]], float [[DATA3]], i8 15)
62+
; CHECK: call void @dx.op.bufferStore.f32(i32 69, %dx.types.Handle %{{.*}}, i32 %offset, i32 undef, float [[DATA0]], float [[DATA1]], float [[DATA2]], float [[DATA3]], i8 15)
6363
call void @llvm.dx.resource.store.rawbuffer.v4f32(
6464
target("dx.RawBuffer", i8, 1, 0, 0) %buffer,
65-
i32 %offset, i32 0, <4 x float> %data)
65+
i32 %offset, i32 poison, <4 x float> %data)
6666

6767
ret void
6868
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
; We use llc for this test so that we don't abort after the first error.
2+
; RUN: not llc %s -o /dev/null 2>&1 | FileCheck %s
3+
4+
target triple = "dxil-pc-shadermodel6.6-compute"
5+
6+
declare void @f32_user(float)
7+
8+
; CHECK: error:
9+
; CHECK-SAME: in function loadrawzero
10+
; CHECK-SAME: Element index of raw buffer must be poison
11+
define void @loadrawzero(i32 %offset) "hlsl.export" {
12+
%buffer = call target("dx.RawBuffer", i8, 0, 0, 0)
13+
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, ptr null)
14+
15+
%load = call {float, i1}
16+
@llvm.dx.resource.load.rawbuffer(
17+
target("dx.RawBuffer", i8, 0, 0, 0) %buffer,
18+
i32 %offset,
19+
i32 0)
20+
%data = extractvalue {float, i1} %load, 0
21+
22+
call void @f32_user(float %data)
23+
24+
ret void
25+
}
26+
27+
; CHECK: error:
28+
; CHECK-SAME: in function loadstructundef
29+
; CHECK-SAME: Element index of structured buffer may not be poison
30+
define void @loadstructundef(i32 %index) "hlsl.export" {
31+
%buffer = call target("dx.RawBuffer", float, 0, 0, 0)
32+
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, ptr null)
33+
34+
%load = call {float, i1}
35+
@llvm.dx.resource.load.rawbuffer(
36+
target("dx.RawBuffer", float, 0, 0, 0) %buffer,
37+
i32 %index,
38+
i32 poison)
39+
%data = extractvalue {float, i1} %load, 0
40+
call void @f32_user(float %data)
41+
42+
ret void
43+
}
44+
45+
; CHECK: error:
46+
; CHECK-SAME: in function storerawzero
47+
; CHECK-SAME: Element index of raw buffer must be poison
48+
define void @storerawzero(i32 %offset, float %data) {
49+
%buffer = call target("dx.RawBuffer", i8, 1, 0, 0)
50+
@llvm.dx.resource.handlefrombinding(
51+
i32 0, i32 0, i32 1, i32 0, ptr null)
52+
53+
call void @llvm.dx.resource.store.rawbuffer(
54+
target("dx.RawBuffer", i8, 1, 0, 0) %buffer,
55+
i32 %offset, i32 0, float %data)
56+
57+
ret void
58+
}
59+
60+
; CHECK: error:
61+
; CHECK-SAME: in function storestructundef
62+
; CHECK-SAME: Element index of structured buffer may not be poison
63+
define void @storestructundef(i32 %index, float %data) {
64+
%buffer = call target("dx.RawBuffer", float, 1, 0, 0)
65+
@llvm.dx.resource.handlefrombinding(
66+
i32 0, i32 0, i32 1, i32 0, ptr null)
67+
68+
call void @llvm.dx.resource.store.rawbuffer(
69+
target("dx.RawBuffer", float, 1, 0, 0) %buffer,
70+
i32 %index, i32 poison, float %data)
71+
72+
ret void
73+
}
74+
75+
declare { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_i8_0_0_0t(target("dx.RawBuffer", i8, 0, 0, 0), i32, i32)
76+
declare { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_0_0_0t(target("dx.RawBuffer", float, 0, 0, 0), i32, i32)
77+
declare void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i8_1_0_0t.f32(target("dx.RawBuffer", i8, 1, 0, 0), i32, i32, float)
78+
declare void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_f32_1_0_0t.f32(target("dx.RawBuffer", float, 1, 0, 0), i32, i32, float)

llvm/test/CodeGen/DirectX/RawBufferLoad.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ define void @loadf32_byte(i32 %offset) {
3636
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0_0(
3737
i32 0, i32 0, i32 1, i32 0, ptr null)
3838

39-
; CHECK: [[DATA:%.*]] = call %dx.types.ResRet.f32 @dx.op.rawBufferLoad.f32(i32 139, %dx.types.Handle %{{.*}}, i32 %offset, i32 0, i8 1, i32 4)
39+
; CHECK: [[DATA:%.*]] = call %dx.types.ResRet.f32 @dx.op.rawBufferLoad.f32(i32 139, %dx.types.Handle %{{.*}}, i32 %offset, i32 undef, i8 1, i32 4)
4040
%load = call {float, i1}
4141
@llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_i8_0_0_0t(
4242
target("dx.RawBuffer", i8, 0, 0, 0) %buffer,
4343
i32 %offset,
44-
i32 0)
44+
i32 poison)
4545
%data = extractvalue {float, i1} %load, 0
4646

4747
; CHECK: [[VAL:%.*]] = extractvalue %dx.types.ResRet.f32 [[DATA]], 0
@@ -85,12 +85,12 @@ define void @loadv4f32_byte(i32 %offset) {
8585
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0_0(
8686
i32 0, i32 0, i32 1, i32 0, ptr null)
8787

88-
; CHECK: [[DATA:%.*]] = call %dx.types.ResRet.f32 @dx.op.rawBufferLoad.f32(i32 139, %dx.types.Handle %{{.*}}, i32 %offset, i32 0, i8 15, i32 4)
88+
; CHECK: [[DATA:%.*]] = call %dx.types.ResRet.f32 @dx.op.rawBufferLoad.f32(i32 139, %dx.types.Handle %{{.*}}, i32 %offset, i32 undef, i8 15, i32 4)
8989
%load = call {<4 x float>, i1}
9090
@llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_i8_0_0_0t(
9191
target("dx.RawBuffer", i8, 0, 0, 0) %buffer,
9292
i32 %offset,
93-
i32 0)
93+
i32 poison)
9494
%data = extractvalue {<4 x float>, i1} %load, 0
9595

9696
; CHECK: extractvalue %dx.types.ResRet.f32 [[DATA]], 0
@@ -212,9 +212,9 @@ define void @loadv4f64_byte(i32 %offset) {
212212
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0_0(
213213
i32 0, i32 0, i32 1, i32 0, ptr null)
214214

215-
; CHECK: [[DATA:%.*]] = call %dx.types.ResRet.f64 @dx.op.rawBufferLoad.f64(i32 139, %dx.types.Handle %{{.*}}, i32 %offset, i32 0, i8 15, i32 8)
215+
; CHECK: [[DATA:%.*]] = call %dx.types.ResRet.f64 @dx.op.rawBufferLoad.f64(i32 139, %dx.types.Handle %{{.*}}, i32 %offset, i32 undef, i8 15, i32 8)
216216
%load = call {<4 x double>, i1} @llvm.dx.resource.load.rawbuffer.v4i64(
217-
target("dx.RawBuffer", i8, 0, 0, 0) %buffer, i32 %offset, i32 0)
217+
target("dx.RawBuffer", i8, 0, 0, 0) %buffer, i32 %offset, i32 poison)
218218
%data = extractvalue {<4 x double>, i1} %load, 0
219219

220220
; CHECK: extractvalue %dx.types.ResRet.f64 [[DATA]], 0

llvm/test/CodeGen/DirectX/RawBufferStore.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ define void @storef32_byte(i32 %offset, float %data) {
2222
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0_0(
2323
i32 0, i32 0, i32 1, i32 0, ptr null)
2424

25-
; CHECK: call void @dx.op.rawBufferStore.f32(i32 140, %dx.types.Handle %buffer_annot, i32 %offset, i32 0, float %data, float undef, float undef, float undef, i8 1, i32 4)
25+
; CHECK: call void @dx.op.rawBufferStore.f32(i32 140, %dx.types.Handle %buffer_annot, i32 %offset, i32 undef, float %data, float undef, float undef, float undef, i8 1, i32 4)
2626
call void @llvm.dx.resource.store.rawbuffer.f32(
2727
target("dx.RawBuffer", i8, 1, 0, 0) %buffer,
28-
i32 %offset, i32 0, float %data)
28+
i32 %offset, i32 poison, float %data)
2929

3030
ret void
3131
}
@@ -58,10 +58,10 @@ define void @storev4f32_byte(i32 %offset, <4 x float> %data) {
5858
; CHECK: [[DATA1:%.*]] = extractelement <4 x float> %data, i32 1
5959
; CHECK: [[DATA2:%.*]] = extractelement <4 x float> %data, i32 2
6060
; CHECK: [[DATA3:%.*]] = extractelement <4 x float> %data, i32 3
61-
; CHECK: call void @dx.op.rawBufferStore.f32(i32 140, %dx.types.Handle %buffer_annot, i32 %offset, i32 0, float [[DATA0]], float [[DATA1]], float [[DATA2]], float [[DATA3]], i8 15, i32 4)
61+
; CHECK: call void @dx.op.rawBufferStore.f32(i32 140, %dx.types.Handle %buffer_annot, i32 %offset, i32 undef, float [[DATA0]], float [[DATA1]], float [[DATA2]], float [[DATA3]], i8 15, i32 4)
6262
call void @llvm.dx.resource.store.rawbuffer.v4f32(
6363
target("dx.RawBuffer", i8, 1, 0, 0) %buffer,
64-
i32 %offset, i32 0, <4 x float> %data)
64+
i32 %offset, i32 poison, <4 x float> %data)
6565

6666
ret void
6767
}
@@ -135,10 +135,10 @@ define void @storev4f64_byte(i32 %offset, <4 x double> %data) {
135135
; CHECK: [[DATA1:%.*]] = extractelement <4 x double> %data, i32 1
136136
; CHECK: [[DATA2:%.*]] = extractelement <4 x double> %data, i32 2
137137
; CHECK: [[DATA3:%.*]] = extractelement <4 x double> %data, i32 3
138-
; CHECK: call void @dx.op.rawBufferStore.f64(i32 140, %dx.types.Handle %buffer_annot, i32 %offset, i32 0, double [[DATA0]], double [[DATA1]], double [[DATA2]], double [[DATA3]], i8 15, i32 8)
138+
; CHECK: call void @dx.op.rawBufferStore.f64(i32 140, %dx.types.Handle %buffer_annot, i32 %offset, i32 undef, double [[DATA0]], double [[DATA1]], double [[DATA2]], double [[DATA3]], i8 15, i32 8)
139139
call void @llvm.dx.resource.store.rawbuffer.v4i64(
140140
target("dx.RawBuffer", i8, 1, 0, 0) %buffer,
141-
i32 %offset, i32 0, <4 x double> %data)
141+
i32 %offset, i32 poison, <4 x double> %data)
142142

143143
ret void
144144
}

0 commit comments

Comments
 (0)