Skip to content

Commit 659f2fc

Browse files
committed
Include HLSL or_intrinsic, add codegen in CGBuiltin, and the corresponding tests in or.hlsl. Additionally, incorporate logical-operator-errors to handle both 'and' and 'or' semantic diagnostics.
1 parent aa69604 commit 659f2fc

File tree

5 files changed

+142
-0
lines changed

5 files changed

+142
-0
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4783,6 +4783,12 @@ def HLSLAnd : LangBuiltin<"HLSL_LANG"> {
47834783
let Prototype = "void(...)";
47844784
}
47854785

4786+
def HLSLOr : LangBuiltin<"HLSL_LANG"> {
4787+
let Spellings = ["__builtin_hlsl_or"];
4788+
let Attributes = [NoThrow, Const];
4789+
let Prototype = "void(...)";
4790+
}
4791+
47864792
def HLSLAny : LangBuiltin<"HLSL_LANG"> {
47874793
let Spellings = ["__builtin_hlsl_any"];
47884794
let Attributes = [NoThrow, Const];

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19492,6 +19492,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
1949219492
Value *Op1 = EmitScalarExpr(E->getArg(1));
1949319493
return Builder.CreateAnd(Op0, Op1, "hlsl.and");
1949419494
}
19495+
case Builtin::BI__builtin_hlsl_or: {
19496+
Value *Op0 = EmitScalarExpr(E->getArg(0));
19497+
Value *Op1 = EmitScalarExpr(E->getArg(1));
19498+
return Builder.CreateOr(Op0, Op1, "hlsl.or");
19499+
}
1949519500
case Builtin::BI__builtin_hlsl_any: {
1949619501
Value *Op0 = EmitScalarExpr(E->getArg(0));
1949719502
return Builder.CreateIntrinsic(

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2305,6 +2305,25 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
23052305
TheCall->setType(ArgTyA);
23062306
break;
23072307
}
2308+
case Builtin::BI__builtin_hlsl_or: {
2309+
if (SemaRef.checkArgCount(TheCall, 2))
2310+
return true;
2311+
if (CheckVectorElementCallArgs(&SemaRef, TheCall))
2312+
return true;
2313+
2314+
// Ensure input expr type is a scalar/vector and the same as the return type
2315+
if (CheckScalarOrVector(&SemaRef, TheCall, getASTContext().BoolTy, 0))
2316+
return true;
2317+
2318+
// Ensure input parameter type is bool
2319+
ExprResult A = TheCall->getArg(0);
2320+
QualType ArgTyA = A.get()->getType();
2321+
2322+
// return type is the same as the input type
2323+
TheCall->setType(ArgTyA);
2324+
2325+
break;
2326+
}
23082327
case Builtin::BI__builtin_hlsl_all:
23092328
case Builtin::BI__builtin_hlsl_any: {
23102329
if (SemaRef.checkArgCount(TheCall, 1))
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// RUN: %clang_cc1 -finclude-default-header -triple \
2+
// RUN: dxil-pc-shadermodel6.3-library %s \
3+
// RUN: -emit-llvm -O1 -o - | FileCheck %s
4+
5+
//CHECK-LABEL: define noundef i1 @_Z12test_or_boolbb(
6+
//CHECK-SAME: i1 noundef [[X:%.*]], i1 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
7+
//CHECK-NEXT: [[ENTRY:.*:]]
8+
//CHECK-NEXT: [[HLSL_OR:%.*]] = or i1 [[x]], [[y]]
9+
//CHECK-NEXT: ret i1 [[HLSL_OR]]
10+
//CHECK_NEXT: }
11+
bool test_or_bool(bool x, bool y)
12+
{
13+
return or(x, y);
14+
15+
}
16+
17+
//CHECK-LABEL: define noundef <2 x i1> @_Z13test_or_bool2Dv2_bS_(
18+
//CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
19+
//CHECK-NEXT: [[ENTRY:.*:]]
20+
//CHECK-NEXT: [[HLSL_OR:%.*]] = or <2 xi1> [[x]], [[y]]
21+
//CHECK-NEXT: ret <2 x i1> [[HLSL_OR]]
22+
//CHECK_NEXT: }
23+
bool2 test_or_bool2(bool2 x, bool2 y)
24+
{
25+
return or(x, y);
26+
}
27+
28+
//CHECK-LABEL: define noundef <3 x i1> @_Z13test_or_bool3Dv3_bS_(
29+
//CHECK-SAME: <3 x i1> noundef [[X:%.*]], <3 x i1> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
30+
//CHECK-NEXT: [[ENTRY:.*:]]
31+
//CHECK-NEXT: [[HLSL_OR:%.*]] = or <3 xi1> [[x]], [[y]]
32+
//CHECK-NEXT: ret <3 x i1> [[HLSL_OR]]
33+
//CHECK_NEXT: }
34+
bool3 test_or_bool3(bool3 x, bool3 y)
35+
{
36+
return or(x, y);
37+
}
38+
39+
//CHECK-LABEL: define noundef <4 x i1> @_Z13test_or_bool4Dv4_bS_(
40+
//CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
41+
//CHECK-NEXT: [[ENTRY:.*:]]
42+
//CHECK-NEXT: [[HLSL_OR:%.*]] = or <4 xi1> [[x]], [[y]]
43+
//CHECK-NEXT: ret <4 x i1> [[HLSL_OR]]
44+
//CHECK_NEXT: }
45+
bool4 test_or_bool4(bool4 x, bool4 y)
46+
{
47+
return or(x, y);
48+
}
49+
50+
//CHECK-LABEL: define noundef i1 @_Z11test_or_intii(
51+
//CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
52+
//CHECK-NEXT: [[ENTRY:.*:]]
53+
//CHECK_NEXT: [[0:%.*]] = or i32 [[y]], [[x]]
54+
//CHECK-NEXT: [[HLSL_OR:%.*]] = icmp ne i32 [[0]], 0
55+
//CHECK-NEXT: ret i1 [[HLSL_OR]]
56+
//CHECK_NEXT: }
57+
bool test_or_int(int x, int y)
58+
{
59+
return or(x, y);
60+
}
61+
62+
//CHECK-LABEL: define noundef <4 x i1> @_Z12test_or_int4Dv4_iS_(
63+
//CHECK-SAME: <4 x i32> noundef [[X:%.*]], <4 x i32> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
64+
//CHECK-NEXT: [[ENTRY:.*:]]
65+
//CHECK_NEXT: [[0:%.*]] = or <4 x i32> [[y]], [[x]]
66+
//CHECK-NEXT: [[HLSL_OR:%.*]] = icmp ne <4 x i32> [[0]], zeroinitializer
67+
//CHECK-NEXT: ret <4 x i1> [[HLSL_OR]]
68+
//CHECK_NEXT: }
69+
bool4 test_or_int4(int4 x, int4 y)
70+
{
71+
return or(x, y);
72+
}
73+
74+
//CHECK-LABEL: noundef <4 x i1> @_Z14test_or_float4Dv4_fS_(
75+
//CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[X:%.*]], <4 x float> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
76+
//CHECK-NEXT: [[ENTRY:.*:]]
77+
//CHECK-NEXT: [[TOBOOL:%.*]] = fcmp reassoc nnan ninf nsz arcp afn une <4 x float> [[X]], zeroinitializer
78+
//CHECK-NEXT: [[TOBOOL1:%.*]] = fcmp reassoc nnan ninf nsz arcp afn une <4 x float> [[Y]], zeroinitializer
79+
//CHECK-NEXT: [[HLSL_OR:%.*]] = or <4 x i1> [[TOBOOL]], [[TOBOOL1]]
80+
//CHECK-NEXT: ret <4 x i1> [[HLSL_OR]]
81+
//CHECK_NEXT: }
82+
bool4 test_or_float4(float4 x, float4 y)
83+
{
84+
return or(x, y);
85+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -verify -DTEST_FUNC=__builtin_hlsl_or
2+
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -verify -DTEST_FUNC=__builtin_hlsl_and
3+
4+
5+
bool test_too_few_arg(bool a)
6+
{
7+
return TEST_FUNC(a);
8+
// expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
9+
}
10+
11+
bool test_too_many_arg(bool a)
12+
{
13+
return TEST_FUNC(a, a, a);
14+
// expected-error@-1 {{too many arguments to function call, expected 2, have 3}}
15+
}
16+
17+
bool2 test_mismatched_args(bool2 a, bool3 b)
18+
{
19+
return TEST_FUNC(a, b);
20+
// expected-error@-1 {{all arguments to}}{{.*}}{{must have the same type}}
21+
}
22+
23+
bool test_incorrect_type(int a)
24+
{
25+
return TEST_FUNC(a, a);
26+
// expected-error@-1{{invalid operand of type 'int' where 'bool' or a vector of such type is required}}
27+
}

0 commit comments

Comments
 (0)