diff --git a/tools/clang/test/CodeGenHLSL/vector-and.hlsl b/tools/clang/test/CodeGenHLSL/vector-and.hlsl new file mode 100644 index 0000000000..d6ae00af2f --- /dev/null +++ b/tools/clang/test/CodeGenHLSL/vector-and.hlsl @@ -0,0 +1,141 @@ +// RUN: %dxc -T ps_6_0 -HV 2021 -DTYPE=bool %s | FileCheck %s --check-prefixes=CHECK,I32 +// RUN: %dxc -T ps_6_0 -HV 2018 -DTYPE=bool %s | FileCheck %s --check-prefixes=CHECK,I32 +// RUN: %dxc -T ps_6_0 -HV 2021 -DTYPE=int %s | FileCheck %s --check-prefixes=CHECK,I32 +// RUN: %dxc -T ps_6_0 -HV 2018 -DTYPE=int %s | FileCheck %s --check-prefixes=CHECK,I32 +// RUN: %dxc -T ps_6_0 -HV 2021 -DTYPE=float %s | FileCheck %s --check-prefixes=CHECK,F32 +// RUN: %dxc -T ps_6_0 -HV 2018 -DTYPE=float %s | FileCheck %s --check-prefixes=CHECK,F32 + +// I32: %dx.types.ResRet.[[TY:i32]] = type { [[TYPE:i32]] +// F32: %dx.types.ResRet.[[TY:f32]] = type { [[TYPE:float]] + +// CHECK-LABEL: define void @main + +ByteAddressBuffer buf; + +float4 main() : SV_Target { + + // CHECK-DAG: [[SAR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 0 + // CHECK-DAG: [[SAX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[SAR]], 0 + // I32-DAG: [[SA:%.*]] = icmp ne i32 [[SAX]], 0 + // F32-DAG: [[SA:%.*]] = fcmp fast une float [[SAX]], 0.000000e+00 + + // CHECK-DAG: [[SBR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 8 + // CHECK-DAG: [[SBX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[SBR]], 0 + // I32-DAG: [[SB:%.*]] = icmp ne i32 [[SBX]], 0 + // F32-DAG: [[SB:%.*]] = fcmp fast une float [[SBX]], 0.000000e+00 + + TYPE sb = buf.Load(8); + TYPE sa = buf.Load(0); + + // CHECK: and i1 [[SB]], [[SA]] + TYPE res = and(sa, sb); + + // CHECK-DAG: [[V1AR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 16 + // CHECK-DAG: [[V1AX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V1AR]], 0 + // I32-DAG: [[V1A:%.*]] = icmp ne i32 [[V1AX]], 0 + // F32-DAG: [[V1A:%.*]] = fcmp fast une float [[V1AX]], 0.000000e+00 + + // CHECK-DAG: [[V1BR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 24 + // CHECK-DAG: [[V1BX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V1BR]], 0 + // I32-DAG: [[V1B:%.*]] = icmp ne i32 [[V1BX]], 0 + // F32-DAG: [[V1B:%.*]] = fcmp fast une float [[V1BX]], 0.000000e+00 + + vector v1b = buf.Load< vector >(24); + vector v1a = buf.Load< vector >(16); + + // CHECK: and i1 [[V1B]], [[V1A]] + vector res1 = and(v1a, v1b); + + // CHECK-DAG: [[V3AR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 32 + // CHECK-DAG: [[V3AX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 0 + // CHECK-DAG: [[V3AX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 1 + // CHECK-DAG: [[V3AX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 2 + + // I32-DAG: [[V3A0:%.*]] = icmp ne i32 [[V3AX0]], 0 + // I32-DAG: [[V3A1:%.*]] = icmp ne i32 [[V3AX1]], 0 + // I32-DAG: [[V3A2:%.*]] = icmp ne i32 [[V3AX2]], 0 + + // F32-DAG: [[V3A0:%.*]] = fcmp fast une float [[V3AX0]], 0.000000e+00 + // F32-DAG: [[V3A1:%.*]] = fcmp fast une float [[V3AX1]], 0.000000e+00 + // F32-DAG: [[V3A2:%.*]] = fcmp fast une float [[V3AX2]], 0.000000e+00 + + // CHECK-DAG: [[V3BR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 56 + // CHECK-DAG: [[V3BX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 0 + // CHECK-DAG: [[V3BX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 1 + // CHECK-DAG: [[V3BX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 2 + + // I32-DAG: [[V3B0:%.*]] = icmp ne i32 [[V3BX0]], 0 + // I32-DAG: [[V3B1:%.*]] = icmp ne i32 [[V3BX1]], 0 + // I32-DAG: [[V3B2:%.*]] = icmp ne i32 [[V3BX2]], 0 + + // F32-DAG: [[V3B0:%.*]] = fcmp fast une float [[V3BX0]], 0.000000e+00 + // F32-DAG: [[V3B1:%.*]] = fcmp fast une float [[V3BX1]], 0.000000e+00 + // F32-DAG: [[V3B2:%.*]] = fcmp fast une float [[V3BX2]], 0.000000e+00 + + vector v3b = buf.Load< vector >(56); + vector v3a = buf.Load< vector >(32); + + // CHECK: and i1 [[V3B0]], [[V3A0]] + // CHECK: and i1 [[V3B1]], [[V3A1]] + // CHECK: and i1 [[V3B2]], [[V3A2]] + vector res3 = and(v3a, v3b); + + // CHECK-DAG: [[MAR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 80 + // CHECK-DAG: [[MAX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 0 + // CHECK-DAG: [[MAX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 1 + // CHECK-DAG: [[MAX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 2 + // CHECK-DAG: [[MAX3:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 3 + // CHECK-DAG: [[MAR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 96 + // CHECK-DAG: [[MAX4:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 0 + // CHECK-DAG: [[MAX5:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 1 + + // I32-DAG: [[MA0:%.*]] = icmp ne i32 [[MAX0]], 0 + // I32-DAG: [[MA1:%.*]] = icmp ne i32 [[MAX1]], 0 + // I32-DAG: [[MA2:%.*]] = icmp ne i32 [[MAX2]], 0 + // I32-DAG: [[MA3:%.*]] = icmp ne i32 [[MAX3]], 0 + // I32-DAG: [[MA4:%.*]] = icmp ne i32 [[MAX4]], 0 + // I32-DAG: [[MA5:%.*]] = icmp ne i32 [[MAX5]], 0 + + // F32-DAG: [[MA0:%.*]] = fcmp fast une float [[MAX0]], 0.000000e+00 + // F32-DAG: [[MA1:%.*]] = fcmp fast une float [[MAX1]], 0.000000e+00 + // F32-DAG: [[MA2:%.*]] = fcmp fast une float [[MAX2]], 0.000000e+00 + // F32-DAG: [[MA3:%.*]] = fcmp fast une float [[MAX3]], 0.000000e+00 + // F32-DAG: [[MA4:%.*]] = fcmp fast une float [[MAX4]], 0.000000e+00 + // F32-DAG: [[MA5:%.*]] = fcmp fast une float [[MAX5]], 0.000000e+00 + + // CHECK-DAG: [[MBR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 128 + // CHECK-DAG: [[MBX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 0 + // CHECK-DAG: [[MBX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 1 + // CHECK-DAG: [[MBX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 2 + // CHECK-DAG: [[MBX3:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 3 + // CHECK-DAG: [[MBR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 144 + // CHECK-DAG: [[MBX4:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 0 + // CHECK-DAG: [[MBX5:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 1 + + // I32-DAG: [[MB0:%.*]] = icmp ne i32 [[MBX0]], 0 + // I32-DAG: [[MB1:%.*]] = icmp ne i32 [[MBX1]], 0 + // I32-DAG: [[MB2:%.*]] = icmp ne i32 [[MBX2]], 0 + // I32-DAG: [[MB3:%.*]] = icmp ne i32 [[MBX3]], 0 + // I32-DAG: [[MB4:%.*]] = icmp ne i32 [[MBX4]], 0 + // I32-DAG: [[MB5:%.*]] = icmp ne i32 [[MBX5]], 0 + + // F32-DAG: [[MB0:%.*]] = fcmp fast une float [[MBX0]], 0.000000e+00 + // F32-DAG: [[MB1:%.*]] = fcmp fast une float [[MBX1]], 0.000000e+00 + // F32-DAG: [[MB2:%.*]] = fcmp fast une float [[MBX2]], 0.000000e+00 + // F32-DAG: [[MB3:%.*]] = fcmp fast une float [[MBX3]], 0.000000e+00 + // F32-DAG: [[MB4:%.*]] = fcmp fast une float [[MBX4]], 0.000000e+00 + // F32-DAG: [[MB5:%.*]] = fcmp fast une float [[MBX5]], 0.000000e+00 + + matrix matb = buf.Load< matrix >(128); + matrix mata = buf.Load< matrix >(80); + + // CHECK: and i1 [[MB0]], [[MA0]] + // CHECK: and i1 [[MB1]], [[MA1]] + // CHECK: and i1 [[MB2]], [[MA2]] + // CHECK: and i1 [[MB3]], [[MA3]] + // CHECK: and i1 [[MB4]], [[MA4]] + // CHECK: and i1 [[MB5]], [[MA5]] + matrix resmat = and(mata, matb); + + return float4(res3 + resmat[0] + resmat[1], res + res1.x); +} diff --git a/tools/clang/test/CodeGenHLSL/vector-or.hlsl b/tools/clang/test/CodeGenHLSL/vector-or.hlsl new file mode 100644 index 0000000000..2fe6c72434 --- /dev/null +++ b/tools/clang/test/CodeGenHLSL/vector-or.hlsl @@ -0,0 +1,164 @@ +// RUN: %dxc -T ps_6_0 -HV 2021 -DTYPE=bool %s | FileCheck %s --check-prefixes=CHECK,I32 +// RUN: %dxc -T ps_6_0 -HV 2018 -DTYPE=bool %s | FileCheck %s --check-prefixes=CHECK,I32 +// RUN: %dxc -T ps_6_0 -HV 2021 -DTYPE=int %s | FileCheck %s --check-prefixes=CHECK,I32 +// RUN: %dxc -T ps_6_0 -HV 2018 -DTYPE=int %s | FileCheck %s --check-prefixes=CHECK,I32 +// RUN: %dxc -T ps_6_0 -HV 2021 -DTYPE=float %s | FileCheck %s --check-prefixes=CHECK,F32 +// RUN: %dxc -T ps_6_0 -HV 2018 -DTYPE=float %s | FileCheck %s --check-prefixes=CHECK,F32 + +// I32: %dx.types.ResRet.[[TY:i32]] = type { [[TYPE:i32]] +// F32: %dx.types.ResRet.[[TY:f32]] = type { [[TYPE:float]] + +// CHECK-LABEL: define void @main + +ByteAddressBuffer buf; + +float4 main() : SV_Target { + + // CHECK: [[SAR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 0 + // F32: [[SAX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[SAR]], 0 + // I32: [[SA:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[SAR]], 0 + + // CHECK: [[SBR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 8 + // F32: [[SBX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[SBR]], 0 + // I32: [[SB:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[SBR]], 0 + + // F32: [[SA:%.*]] = fcmp fast une float [[SAX]], 0.000000e+00 + // F32: [[SB:%.*]] = fcmp fast une float [[SBX]], 0.000000e+00 + + TYPE sa = buf.Load(0); + TYPE sb = buf.Load(8); + + // I32: or i32 [[SB]], [[SA]] + // F32: or i1 [[SA]], [[SB]] + + TYPE res = or(sb, sa); + + // CHECK: [[V1AR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 16 + // F32: [[V1AX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V1AR]], 0 + // I32: [[V1A:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V1AR]], 0 + + // CHECK: [[V1BR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 24 + // F32: [[V1BX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V1BR]], 0 + // I32: [[V1B:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V1BR]], 0 + + // F32: [[V1B:%.*]] = fcmp fast une float [[V1BX]], 0.000000e+00 + // F32: [[V1A:%.*]] = fcmp fast une float [[V1AX]], 0.000000e+00 + + vector v1a = buf.Load< vector >(16); + vector v1b = buf.Load< vector >(24); + + // I32: or i32 [[V1B]], [[V1A]] + // F32: or i1 [[V1A]], [[V1B]] + + vector res1 = or(v1a, v1b); + + // CHECK: [[V3AR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 32 + // F32: [[V3AX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 0 + // F32: [[V3AX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 1 + // F32: [[V3AX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 2 + + // I32: [[V3A0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 0 + // I32: [[V3A1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 1 + // I32: [[V3A2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 2 + + // CHECK: [[V3BR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 56 + // F32: [[V3BX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 0 + // F32: [[V3BX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 1 + // F32: [[V3BX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 2 + + // I32: [[V3B0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 0 + // I32: [[V3B1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 1 + // I32: [[V3B2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 2 + + // F32: [[V3B0:%.*]] = fcmp fast une float [[V3BX0]], 0.000000e+00 + // F32: [[V3B1:%.*]] = fcmp fast une float [[V3BX1]], 0.000000e+00 + // F32: [[V3B2:%.*]] = fcmp fast une float [[V3BX2]], 0.000000e+00 + + // F32: [[V3A0:%.*]] = fcmp fast une float [[V3AX0]], 0.000000e+00 + // F32: [[V3A1:%.*]] = fcmp fast une float [[V3AX1]], 0.000000e+00 + // F32: [[V3A2:%.*]] = fcmp fast une float [[V3AX2]], 0.000000e+00 + + vector v3a = buf.Load< vector >(32); + vector v3b = buf.Load< vector >(56); + + // I32: or i32 [[V3B0]], [[V3A0]] + // I32: or i32 [[V3B1]], [[V3A1]] + // I32: or i32 [[V3B2]], [[V3A2]] + + // F32: or i1 [[V3A0]], [[V3B0]] + // F32: or i1 [[V3A1]], [[V3B1]] + // F32: or i1 [[V3A2]], [[V3B2]] + + vector res3 = or(v3a, v3b); + + // CHECK: [[MAR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 80 + // F32: [[MAX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 0 + // F32: [[MAX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 1 + // F32: [[MAX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 2 + // F32: [[MAX3:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 3 + + // I32: [[MA0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 0 + // I32: [[MA1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 1 + // I32: [[MA2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 2 + // I32: [[MA3:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 3 + + // CHECK: [[MAR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 96 + // F32: [[MAX4:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 0 + // F32: [[MAX5:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 1 + + // I32: [[MA4:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 0 + // I32: [[MA5:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 1 + + // CHECK: [[MBR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 128 + // F32: [[MBX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 0 + // F32: [[MBX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 1 + // F32: [[MBX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 2 + // F32: [[MBX3:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 3 + + // I32: [[MB0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 0 + // I32: [[MB1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 1 + // I32: [[MB2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 2 + // I32: [[MB3:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 3 + + // CHECK: [[MBR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 144 + // F32: [[MBX4:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 0 + // F32: [[MBX5:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 1 + + // I32: [[MB4:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 0 + // I32: [[MB5:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 1 + + // F32: [[MB0:%.*]] = fcmp fast une float [[MBX0]], 0.000000e+00 + // F32: [[MB1:%.*]] = fcmp fast une float [[MBX1]], 0.000000e+00 + // F32: [[MB2:%.*]] = fcmp fast une float [[MBX2]], 0.000000e+00 + // F32: [[MB3:%.*]] = fcmp fast une float [[MBX3]], 0.000000e+00 + // F32: [[MB4:%.*]] = fcmp fast une float [[MBX4]], 0.000000e+00 + // F32: [[MB5:%.*]] = fcmp fast une float [[MBX5]], 0.000000e+00 + + // F32: [[MA0:%.*]] = fcmp fast une float [[MAX0]], 0.000000e+00 + // F32: [[MA1:%.*]] = fcmp fast une float [[MAX1]], 0.000000e+00 + // F32: [[MA2:%.*]] = fcmp fast une float [[MAX2]], 0.000000e+00 + // F32: [[MA3:%.*]] = fcmp fast une float [[MAX3]], 0.000000e+00 + // F32: [[MA4:%.*]] = fcmp fast une float [[MAX4]], 0.000000e+00 + // F32: [[MA5:%.*]] = fcmp fast une float [[MAX5]], 0.000000e+00 + + matrix mata = buf.Load< matrix >(80); + matrix matb = buf.Load< matrix >(128); + + // I32: or i32 [[MB0]], [[MA0]] + // I32: or i32 [[MB1]], [[MA1]] + // I32: or i32 [[MB2]], [[MA2]] + // I32: or i32 [[MB3]], [[MA3]] + // I32: or i32 [[MB4]], [[MA4]] + // I32: or i32 [[MB5]], [[MA5]] + + // F32: or i1 [[MA0]], [[MB0]] + // F32: or i1 [[MA1]], [[MB1]] + // F32: or i1 [[MA2]], [[MB2]] + // F32: or i1 [[MA3]], [[MB3]] + // F32: or i1 [[MA4]], [[MB4]] + // F32: or i1 [[MA5]], [[MB5]] + + matrix resmat = or(mata, matb); + + return float4(res3 + resmat[0] + resmat[1], res + res1.x); +} diff --git a/tools/clang/test/CodeGenSPIRV/intrinsics.and.hlsl b/tools/clang/test/CodeGenSPIRV/intrinsics.and.hlsl index a983e20c45..970faf6a8d 100644 --- a/tools/clang/test/CodeGenSPIRV/intrinsics.and.hlsl +++ b/tools/clang/test/CodeGenSPIRV/intrinsics.and.hlsl @@ -1,6 +1,9 @@ // RUN: %dxc -T ps_6_0 -E main -HV 2021 -fcgl %s -spirv | FileCheck %s // RUN: %dxc -T ps_6_0 -E main -HV 2018 -fcgl %s -spirv | FileCheck %s +// CHECK-DAG: [[v3_0:%[0-9]+]] = OpConstantComposite %v3int %int_0 %int_0 %int_0 +// CHECK-DAG: [[v3_1:%[0-9]+]] = OpConstantComposite %v3int %int_1 %int_1 %int_1 + void main() { // CHECK-LABEL: %bb_entry = OpLabel @@ -33,4 +36,46 @@ void main() { // CHECK-NEXT: [[and3:%[0-9]+]] = OpLogicalAnd %bool [[a1]] [[b1]] // CHECK-NEXT: {{%[0-9]+}} = OpCompositeConstruct %v2bool [[and3]] %true bool2 t = bool2(and(a, b), true); + + int a_0, b_0, c_0; + // Plain assign (scalar) +// CHECK: [[a0_int:%[0-9]+]] = OpLoad %int %a_0 +// CHECK-NEXT: [[a0:%[0-9]+]] = OpINotEqual %bool [[a0_int]] %int_0 +// CHECK-NEXT: [[b0_int:%[0-9]+]] = OpLoad %int %b_0 +// CHECK-NEXT: [[b0:%[0-9]+]] = OpINotEqual %bool [[b0_int]] %int_0 +// CHECK-NEXT: [[and0:%[0-9]+]] = OpLogicalAnd %bool [[a0]] [[b0]] +// CHECK-NEXT: [[sel:%[0-9]+]] = OpSelect %int [[and0]] %int_1 %int_0 +// CHECK-NEXT: OpStore %c_0 [[sel]] + c_0 = and(a_0, b_0); + + int1 i_0, j_0, k_0; + int3 o_0, p_0, q_0; + // Plain assign (vector) +// CHECK-NEXT: [[i0_int:%[0-9]+]] = OpLoad %int %i_0 +// CHECK-NEXT: [[i0:%[0-9]+]] = OpINotEqual %bool [[i0_int]] %int_0 +// CHECK-NEXT: [[j0_int:%[0-9]+]] = OpLoad %int %j_0 +// CHECK-NEXT: [[j0:%[0-9]+]] = OpINotEqual %bool [[j0_int]] %int_0 +// CHECK-NEXT: [[and1:%[0-9]+]] = OpLogicalAnd %bool [[i0]] [[j0]] +// CHECK-NEXT: [[sel:%[0-9]+]] = OpSelect %int [[and1]] %int_1 %int_0 +// CHECK-NEXT: OpStore %k_0 [[sel]] + k_0 = and(i_0, j_0); + +// CHECK-NEXT: [[o0_int:%[0-9]+]] = OpLoad %v3int %o_0 +// CHECK-NEXT: [[o0:%[0-9]+]] = OpINotEqual %v3bool [[o0_int]] [[v3_0]] +// CHECK-NEXT: [[p0_int:%[0-9]+]] = OpLoad %v3int %p_0 +// CHECK-NEXT: [[p0:%[0-9]+]] = OpINotEqual %v3bool [[p0_int]] [[v3_0]] +// CHECK-NEXT: [[and2:%[0-9]+]] = OpLogicalAnd %v3bool [[o0]] [[p0]] +// CHECK-NEXT: [[sel:%[0-9]+]] = OpSelect %v3int [[and2]] [[v3_1]] [[v3_0]] +// CHECK-NEXT: OpStore %q_0 [[sel]] + q_0 = and(o_0, p_0); + +// The result of '&&' could be 'const bool'. In such cases, make sure +// the result type is correct. +// CHECK: [[a0_int:%[0-9]+]] = OpLoad %int %a_0 +// CHECK-NEXT: [[a0:%[0-9]+]] = OpINotEqual %bool [[a0_int]] %int_0 +// CHECK-NEXT: [[b0_int:%[0-9]+]] = OpLoad %int %b_0 +// CHECK-NEXT: [[b0:%[0-9]+]] = OpINotEqual %bool [[b0_int]] %int_0 +// CHECK-NEXT: [[and0:%[0-9]+]] = OpLogicalAnd %bool [[a0]] [[b0]] +// CHECK-NEXT: {{%[0-9]+}} = OpCompositeConstruct %v2bool [[and0]] %true + t = bool2(and(a_0, b_0), true); } diff --git a/tools/clang/test/CodeGenSPIRV/intrinsics.or.hlsl b/tools/clang/test/CodeGenSPIRV/intrinsics.or.hlsl index a61272211e..39a39062f1 100644 --- a/tools/clang/test/CodeGenSPIRV/intrinsics.or.hlsl +++ b/tools/clang/test/CodeGenSPIRV/intrinsics.or.hlsl @@ -1,6 +1,8 @@ // RUN: %dxc -T ps_6_0 -E main -HV 2021 -fcgl %s -spirv | FileCheck %s // RUN: %dxc -T ps_6_0 -E main -HV 2018 -fcgl %s -spirv | FileCheck %s +// CHECK: [[v3_0:%[0-9]+]] = OpConstantComposite %v3int %int_0 %int_0 %int_0 + void main() { // CHECK-LABEL: %bb_entry = OpLabel @@ -25,4 +27,36 @@ void main() { // CHECK-NEXT: OpStore %q [[or2]] k = or(i, j); q = or(o, p); + + int r, s; + bool t; + // Plain assign (scalar) +// CHECK: [[r0_int:%[0-9]+]] = OpLoad %int %r +// CHECK-NEXT: [[r0:%[0-9]+]] = OpINotEqual %bool [[r0_int]] %int_0 +// CHECK-NEXT: [[s0_int:%[0-9]+]] = OpLoad %int %s +// CHECK-NEXT: [[s0:%[0-9]+]] = OpINotEqual %bool [[s0_int]] %int_0 +// CHECK-NEXT: [[or0:%[0-9]+]] = OpLogicalOr %bool [[r0]] [[s0]] +// CHECK-NEXT: OpStore %t [[or0]] + t = or(r, s); + + int1 u, v; + bool1 w; + // Plain assign (vector) +// CHECK-NEXT: [[u0_int:%[0-9]+]] = OpLoad %int %u +// CHECK-NEXT: [[u0:%[0-9]+]] = OpINotEqual %bool [[u0_int]] %int_0 +// CHECK-NEXT: [[v0_int:%[0-9]+]] = OpLoad %int %v +// CHECK-NEXT: [[v0:%[0-9]+]] = OpINotEqual %bool [[v0_int]] %int_0 +// CHECK-NEXT: [[or1:%[0-9]+]] = OpLogicalOr %bool [[u0]] [[v0]] +// CHECK-NEXT: OpStore %w [[or1]] + w = or(u, v); + + int3 x, y; + bool3 z; +// CHECK-NEXT: [[x0_int:%[0-9]+]] = OpLoad %v3int %x +// CHECK-NEXT: [[x0:%[0-9]+]] = OpINotEqual %v3bool [[x0_int]] [[v3_0]] +// CHECK-NEXT: [[y0_int:%[0-9]+]] = OpLoad %v3int %y +// CHECK-NEXT: [[y0:%[0-9]+]] = OpINotEqual %v3bool [[y0_int]] [[v3_0]] +// CHECK-NEXT: [[or2:%[0-9]+]] = OpLogicalOr %v3bool [[x0]] [[y0]] +// CHECK-NEXT: OpStore %z [[or2]] + z = or(x, y); } diff --git a/utils/hct/gen_intrin_main.txt b/utils/hct/gen_intrin_main.txt index 40b5f6d96a..8ee8d0bc99 100644 --- a/utils/hct/gen_intrin_main.txt +++ b/utils/hct/gen_intrin_main.txt @@ -369,8 +369,8 @@ resource [[hidden]] CreateResourceFromHeap(in uint index); // Replacement for vector logical &&, ||, and ternary conditional operators, // For use when HLSL changes to support short-circuiting and only scalar // conditions to maintain clarity. -$match<1, 0> bool<> [[rn]] and(in any<> x, in $type1 y); -$match<1, 0> bool<> [[rn]] or(in any<> x, in $type1 y); +$match<1, 0> bool<> [[rn]] and(in bool<> x, in $type1 y); +$match<1, 0> bool<> [[rn]] or(in bool<> x, in $type1 y); $type2 [[rn]] select(in bool<> cond, in $match<1, 2> any<> t, in $type2 f); $type2 [[rn]] select(in bool cond, in any_sampler t, in $type2 f);