-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[HLSL] get inout/out ABI for array parameters working #111047
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
119def0
3231a7b
67ca255
fe046b9
cd022bb
b65b4ed
b663f00
58577d2
0026eb8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4726,15 +4726,17 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E, | |
| return emitWritebackArg(*this, args, CRE); | ||
| } | ||
|
|
||
| assert(type->isReferenceType() == E->isGLValue() && | ||
| "reference binding to unmaterialized r-value!"); | ||
|
|
||
| // Add writeback for HLSLOutParamExpr. | ||
| // Needs to be before the assert below because HLSLOutArgExpr is an LValue | ||
| // and is not a reference. | ||
| if (const HLSLOutArgExpr *OE = dyn_cast<HLSLOutArgExpr>(E)) { | ||
| EmitHLSLOutArgExpr(OE, args, type); | ||
| return; | ||
| } | ||
|
|
||
| assert(type->isReferenceType() == E->isGLValue() && | ||
| "reference binding to unmaterialized r-value!"); | ||
|
|
||
| if (E->isGLValue()) { | ||
| assert(E->getObjectKind() == OK_Ordinary); | ||
| return args.add(EmitReferenceBindingToExpr(E), type); | ||
|
|
@@ -5322,6 +5324,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, | |
| IRCallArgs[FirstIRArg] = Val; | ||
| break; | ||
| } | ||
| } else if (I->getType()->isArrayParameterType()) { | ||
| // use the tmp created by the HLSLOutArgExpr | ||
| // instead of creating a new one below and copying the tmp into it. | ||
| IRCallArgs[FirstIRArg] = I->getKnownRValue().getScalarVal(); | ||
| break; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this might be the wrong solution. If we instead make the parameter ABI
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bleh... I spent some time today looking at this, and I think I've convinced myself that this is probably the simplest approach. Without this you get a redundant copy because the cast that produces the ArrayParameterType. I have one small request to change the comment above. |
||
| } | ||
|
|
||
| // For non-aggregate args and aggregate args meeting conditions above | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump %s | FileCheck %s | ||
|
|
||
| // CHECK-LABEL: increment | ||
| void increment(inout int Arr[2]) { | ||
| for (int I = 0; I < 2; I++) | ||
| Arr[0] += 2; | ||
| } | ||
|
|
||
| // CHECK-LABEL: call | ||
| // CHECK: CallExpr 0x{{.*}} {{.*}} 'void' | ||
| // CHECK: ImplicitCastExpr 0x{{.*}} {{.*}} 'void (*)(inout int[2])' <FunctionToPointerDecay> | ||
| // CHECK: DeclRefExpr 0x{{.*}} {{.*}} 'void (inout int[2])' lvalue Function 0x{{.*}} 'increment' 'void (inout int[2])' | ||
| // CHECK: HLSLOutArgExpr 0x{{.*}} {{.*}} 'int[2]' lvalue inout | ||
| // CHECK: OpaqueValueExpr [[A:0x.*]] {{.*}} 'int[2]' lvalue | ||
| // CHECK: DeclRefExpr [[B:0x.*]] {{.*}} 'int[2]' lvalue Var [[E:0x.*]] 'A' 'int[2]' | ||
| // CHECK: OpaqueValueExpr [[C:0x.*]] {{.*}} 'int[2]' lvalue | ||
| // CHECK: ImplicitCastExpr [[D:0x.*]] {{.*}} 'int[2]' <HLSLArrayRValue> | ||
| // CHECK: OpaqueValueExpr [[A]] {{.*}} 'int[2]' lvalue | ||
| // CHECK: DeclRefExpr [[B]] {{.*}} 'int[2]' lvalue Var [[E]] 'A' 'int[2]' | ||
| // CHECK: BinaryOperator 0x{{.*}} {{.*}} 'int[2]' lvalue '=' | ||
| // CHECK: OpaqueValueExpr [[A]] {{.*}} 'int[2]' lvalue | ||
| // CHECK: DeclRefExpr 0x{{.*}} {{.*}} 'int[2]' lvalue Var [[E]] 'A' 'int[2]' | ||
| // CHECK: ImplicitCastExpr 0x{{.*}} {{.*}} 'int[2]' <HLSLArrayRValue> | ||
| // CHECK: OpaqueValueExpr [[C]] {{.*}} 'int[2]' lvalue | ||
| // CHECK: ImplicitCastExpr [[D]] {{.*}} 'int[2]' <HLSLArrayRValue> | ||
| // CHECK: OpaqueValueExpr [[A]] {{.*}} 'int[2]' lvalue | ||
| // CHECK: DeclRefExpr [[B]] {{.*}} 'int[2]' lvalue Var [[E]] 'A' 'int[2]' | ||
| export int call() { | ||
| int A[2] = { 0, 1 }; | ||
| increment(A); | ||
| return A[0]; | ||
| } | ||
|
|
||
| // CHECK-LABEL: fn2 | ||
| void fn2(out int Arr[2]) { | ||
| Arr[0] += 5; | ||
| Arr[1] += 6; | ||
| } | ||
|
|
||
| // CHECK-LABEL: call2 | ||
| // CHECK: CallExpr 0x{{.*}} {{.*}} 'void' | ||
| // CHECK: ImplicitCastExpr 0x{{.*}} {{.*}} 'void (*)(out int[2])' <FunctionToPointerDecay> | ||
| // CHECK: DeclRefExpr 0x{{.*}} {{.*}} 'void (out int[2])' lvalue Function 0x{{.*}} 'fn2' 'void (out int[2])' | ||
| // CHECK: HLSLOutArgExpr 0x{{.*}} {{.*}} 'int[2]' lvalue out | ||
| // CHECK: OpaqueValueExpr [[A:0x.*]] {{.*}} 'int[2]' lvalue | ||
| // CHECK: DeclRefExpr [[B:0x.*]] {{.*}} 'int[2]' lvalue Var [[E:0x.*]] 'A' 'int[2]' | ||
| // CHECK: OpaqueValueExpr [[C:0x.*]] {{.*}} 'int[2]' lvalue | ||
| // CHECK: ImplicitCastExpr [[D:0x.*]] {{.*}} 'int[2]' <HLSLArrayRValue> | ||
| // CHECK: OpaqueValueExpr [[A]] {{.*}} 'int[2]' lvalue | ||
| // CHECK: DeclRefExpr [[B]] {{.*}} 'int[2]' lvalue Var [[E]] 'A' 'int[2]' | ||
| // CHECK: BinaryOperator 0x{{.*}} {{.*}} 'int[2]' lvalue '=' | ||
| // CHECK: OpaqueValueExpr [[A]] {{.*}} 'int[2]' lvalue | ||
| // CHECK: DeclRefExpr [[B]] {{.*}} 'int[2]' lvalue Var [[E]] 'A' 'int[2]' | ||
| // CHECK: ImplicitCastExpr 0x{{.*}} {{.*}} 'int[2]' <HLSLArrayRValue> | ||
| // CHECK: OpaqueValueExpr [[C]] {{.*}} 'int[2]' lvalue | ||
| // CHECK: ImplicitCastExpr [[D]] {{.*}} 'int[2]' <HLSLArrayRValue> | ||
| // CHECK: OpaqueValueExpr [[A]] {{.*}} 'int[2]' lvalue | ||
| // CHECK: DeclRefExpr [[B]] {{.*}} 'int[2]' lvalue Var [[E]] 'A' 'int[2]' | ||
| export int call2() { | ||
| int A[2] = { 0, 1 }; | ||
| fn2(A); | ||
| return 1; | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.