-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[HLSL] Add "or" intrinsic #128979
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
[HLSL] Add "or" intrinsic #128979
Conversation
…nding tests in or.hlsl. Additionally, incorporate logical-operator-errors to handle both 'and' and 'or' semantic diagnostics.
…nding tests in or.hlsl. Additionally, incorporate logical-operator-errors to handle both 'and' and 'or' semantic diagnostics.
…lvm-project into hlsl_or_intrinsic
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-clang @llvm/pr-subscribers-hlsl Author: None (metkarpoonam) ChangesInclude 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. Full diff: https://github.com/llvm/llvm-project/pull/128979.diff 7 Files Affected:
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 598ae171b1389..f7027331cd6c5 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4783,6 +4783,12 @@ def HLSLAnd : LangBuiltin<"HLSL_LANG"> {
let Prototype = "void(...)";
}
+def HLSLOr : LangBuiltin<"HLSL_LANG"> {
+ let Spellings = ["__builtin_hlsl_or"];
+ let Attributes = [NoThrow, Const];
+ let Prototype = "void(...)";
+}
+
def HLSLAny : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_any"];
let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 65fac01d58362..599e05819ec7c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19492,6 +19492,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
Value *Op1 = EmitScalarExpr(E->getArg(1));
return Builder.CreateAnd(Op0, Op1, "hlsl.and");
}
+ case Builtin::BI__builtin_hlsl_or: {
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ Value *Op1 = EmitScalarExpr(E->getArg(1));
+ return Builder.CreateOr(Op0, Op1, "hlsl.or");
+ }
case Builtin::BI__builtin_hlsl_any: {
Value *Op0 = EmitScalarExpr(E->getArg(0));
return Builder.CreateIntrinsic(
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 239d7a3f59b77..764cf671dce31 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -290,6 +290,24 @@ _HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
bool4 and(bool4 x, bool4 y);
// clang-format on
+//===----------------------------------------------------------------------===//
+// or builtins
+//===----------------------------------------------------------------------===//
+
+/// \fn T or(T x, T y)
+/// \brief Returns the bitwise OR of the two input values, \a x and \a y.
+/// \param x The first input value and y The second input value.
+///
+/// \returns The logically OR a vector and retuens bool vector.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool or(bool, bool);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool2 or(bool2, bool2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool3 or(bool3, bool3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool4 or(bool4, bool4);
//===----------------------------------------------------------------------===//
// any builtins
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 283a9801fc707..c48512673be58 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2305,6 +2305,25 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
TheCall->setType(ArgTyA);
break;
}
+ case Builtin::BI__builtin_hlsl_or: {
+ if (SemaRef.checkArgCount(TheCall, 2))
+ return true;
+ if (CheckVectorElementCallArgs(&SemaRef, TheCall))
+ return true;
+
+ // Ensure input expr type is a scalar/vector and the same as the return type
+ if (CheckScalarOrVector(&SemaRef, TheCall, getASTContext().BoolTy, 0))
+ return true;
+
+ // Ensure input parameter type is bool
+ ExprResult A = TheCall->getArg(0);
+ QualType ArgTyA = A.get()->getType();
+
+ // return type is the same as the input type
+ TheCall->setType(ArgTyA);
+
+ break;
+ }
case Builtin::BI__builtin_hlsl_all:
case Builtin::BI__builtin_hlsl_any: {
if (SemaRef.checkArgCount(TheCall, 1))
diff --git a/clang/test/CodeGenHLSL/builtins/or.hlsl b/clang/test/CodeGenHLSL/builtins/or.hlsl
new file mode 100644
index 0000000000000..0c21973bda17c
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/or.hlsl
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-library %s \
+// RUN: -emit-llvm -O1 -o - | FileCheck %s
+
+//CHECK-LABEL: define noundef i1 @_Z12test_or_boolbb(
+//CHECK-SAME: i1 noundef [[X:%.*]], i1 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+//CHECK-NEXT: [[ENTRY:.*:]]
+//CHECK-NEXT: [[HLSL_OR:%.*]] = or i1 [[x]], [[y]]
+//CHECK-NEXT: ret i1 [[HLSL_OR]]
+//CHECK_NEXT: }
+bool test_or_bool(bool x, bool y)
+{
+ return or(x, y);
+
+}
+
+//CHECK-LABEL: define noundef <2 x i1> @_Z13test_or_bool2Dv2_bS_(
+//CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
+//CHECK-NEXT: [[ENTRY:.*:]]
+//CHECK-NEXT: [[HLSL_OR:%.*]] = or <2 xi1> [[x]], [[y]]
+//CHECK-NEXT: ret <2 x i1> [[HLSL_OR]]
+//CHECK_NEXT: }
+bool2 test_or_bool2(bool2 x, bool2 y)
+{
+ return or(x, y);
+}
+
+//CHECK-LABEL: define noundef <3 x i1> @_Z13test_or_bool3Dv3_bS_(
+//CHECK-SAME: <3 x i1> noundef [[X:%.*]], <3 x i1> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
+//CHECK-NEXT: [[ENTRY:.*:]]
+//CHECK-NEXT: [[HLSL_OR:%.*]] = or <3 xi1> [[x]], [[y]]
+//CHECK-NEXT: ret <3 x i1> [[HLSL_OR]]
+//CHECK_NEXT: }
+bool3 test_or_bool3(bool3 x, bool3 y)
+{
+ return or(x, y);
+}
+
+//CHECK-LABEL: define noundef <4 x i1> @_Z13test_or_bool4Dv4_bS_(
+//CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
+//CHECK-NEXT: [[ENTRY:.*:]]
+//CHECK-NEXT: [[HLSL_OR:%.*]] = or <4 xi1> [[x]], [[y]]
+//CHECK-NEXT: ret <4 x i1> [[HLSL_OR]]
+//CHECK_NEXT: }
+bool4 test_or_bool4(bool4 x, bool4 y)
+{
+ return or(x, y);
+}
+
+//CHECK-LABEL: define noundef i1 @_Z11test_or_intii(
+//CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
+//CHECK-NEXT: [[ENTRY:.*:]]
+//CHECK_NEXT: [[0:%.*]] = or i32 [[y]], [[x]]
+//CHECK-NEXT: [[HLSL_OR:%.*]] = icmp ne i32 [[0]], 0
+//CHECK-NEXT: ret i1 [[HLSL_OR]]
+//CHECK_NEXT: }
+bool test_or_int(int x, int y)
+{
+ return or(x, y);
+}
+
+//CHECK-LABEL: define noundef <4 x i1> @_Z12test_or_int4Dv4_iS_(
+//CHECK-SAME: <4 x i32> noundef [[X:%.*]], <4 x i32> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
+//CHECK-NEXT: [[ENTRY:.*:]]
+//CHECK_NEXT: [[0:%.*]] = or <4 x i32> [[y]], [[x]]
+//CHECK-NEXT: [[HLSL_OR:%.*]] = icmp ne <4 x i32> [[0]], zeroinitializer
+//CHECK-NEXT: ret <4 x i1> [[HLSL_OR]]
+//CHECK_NEXT: }
+bool4 test_or_int4(int4 x, int4 y)
+{
+ return or(x, y);
+}
+
+//CHECK-LABEL: noundef <4 x i1> @_Z14test_or_float4Dv4_fS_(
+//CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[X:%.*]], <4 x float> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
+//CHECK-NEXT: [[ENTRY:.*:]]
+//CHECK-NEXT: [[TOBOOL:%.*]] = fcmp reassoc nnan ninf nsz arcp afn une <4 x float> [[X]], zeroinitializer
+//CHECK-NEXT: [[TOBOOL1:%.*]] = fcmp reassoc nnan ninf nsz arcp afn une <4 x float> [[Y]], zeroinitializer
+//CHECK-NEXT: [[HLSL_OR:%.*]] = or <4 x i1> [[TOBOOL]], [[TOBOOL1]]
+//CHECK-NEXT: ret <4 x i1> [[HLSL_OR]]
+//CHECK_NEXT: }
+bool4 test_or_float4(float4 x, float4 y)
+{
+ return or(x, y);
+}
\ No newline at end of file
diff --git a/clang/test/SemaHLSL/BuiltIns/and-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/and-errors.hlsl
deleted file mode 100644
index d9721140b9bf9..0000000000000
--- a/clang/test/SemaHLSL/BuiltIns/and-errors.hlsl
+++ /dev/null
@@ -1,22 +0,0 @@
-// RUN: %clang_cc1 -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-library %s -O1 -verify
-
-bool test_too_few_arg(bool a) {
- return __builtin_hlsl_and(a);
- // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
-}
-
-bool test_too_many_arg(bool a) {
- return __builtin_hlsl_and(a, a, a);
- // expected-error@-1 {{too many arguments to function call, expected 2, have 3}}
-}
-
-bool2 test_mismatched_args(bool2 a, bool3 b) {
- return __builtin_hlsl_and(a, b);
- // expected-error@-1 {{all arguments to '__builtin_hlsl_and' must have the same type}}
-}
-
-bool test_incorrect_type(int a) {
- return __builtin_hlsl_and(a, a);
- // expected-error@-1{{invalid operand of type 'int' where 'bool' or a vector of such type is required}}
-}
diff --git a/clang/test/SemaHLSL/BuiltIns/logical-operator-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/logical-operator-errors.hlsl
new file mode 100644
index 0000000000000..41bf3c4b2f663
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/logical-operator-errors.hlsl
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -verify -DTEST_FUNC=__builtin_hlsl_or
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -verify -DTEST_FUNC=__builtin_hlsl_and
+
+
+bool test_too_few_arg(bool a)
+{
+ return TEST_FUNC(a);
+ // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
+}
+
+bool test_too_many_arg(bool a)
+{
+ return TEST_FUNC(a, a, a);
+ // expected-error@-1 {{too many arguments to function call, expected 2, have 3}}
+}
+
+bool2 test_mismatched_args(bool2 a, bool3 b)
+{
+ return TEST_FUNC(a, b);
+ // expected-error@-1 {{all arguments to}}{{.*}}{{must have the same type}}
+}
+
+bool test_incorrect_type(int a)
+{
+ return TEST_FUNC(a, a);
+ // expected-error@-1{{invalid operand of type 'int' where 'bool' or a vector of such type is required}}
+}
\ No newline at end of file
|
@llvm/pr-subscribers-backend-x86 Author: None (metkarpoonam) ChangesInclude 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. Full diff: https://github.com/llvm/llvm-project/pull/128979.diff 7 Files Affected:
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 598ae171b1389..f7027331cd6c5 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4783,6 +4783,12 @@ def HLSLAnd : LangBuiltin<"HLSL_LANG"> {
let Prototype = "void(...)";
}
+def HLSLOr : LangBuiltin<"HLSL_LANG"> {
+ let Spellings = ["__builtin_hlsl_or"];
+ let Attributes = [NoThrow, Const];
+ let Prototype = "void(...)";
+}
+
def HLSLAny : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_any"];
let Attributes = [NoThrow, Const];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 65fac01d58362..599e05819ec7c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19492,6 +19492,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
Value *Op1 = EmitScalarExpr(E->getArg(1));
return Builder.CreateAnd(Op0, Op1, "hlsl.and");
}
+ case Builtin::BI__builtin_hlsl_or: {
+ Value *Op0 = EmitScalarExpr(E->getArg(0));
+ Value *Op1 = EmitScalarExpr(E->getArg(1));
+ return Builder.CreateOr(Op0, Op1, "hlsl.or");
+ }
case Builtin::BI__builtin_hlsl_any: {
Value *Op0 = EmitScalarExpr(E->getArg(0));
return Builder.CreateIntrinsic(
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 239d7a3f59b77..764cf671dce31 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -290,6 +290,24 @@ _HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
bool4 and(bool4 x, bool4 y);
// clang-format on
+//===----------------------------------------------------------------------===//
+// or builtins
+//===----------------------------------------------------------------------===//
+
+/// \fn T or(T x, T y)
+/// \brief Returns the bitwise OR of the two input values, \a x and \a y.
+/// \param x The first input value and y The second input value.
+///
+/// \returns The logically OR a vector and retuens bool vector.
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool or(bool, bool);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool2 or(bool2, bool2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool3 or(bool3, bool3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool4 or(bool4, bool4);
//===----------------------------------------------------------------------===//
// any builtins
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 283a9801fc707..c48512673be58 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2305,6 +2305,25 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
TheCall->setType(ArgTyA);
break;
}
+ case Builtin::BI__builtin_hlsl_or: {
+ if (SemaRef.checkArgCount(TheCall, 2))
+ return true;
+ if (CheckVectorElementCallArgs(&SemaRef, TheCall))
+ return true;
+
+ // Ensure input expr type is a scalar/vector and the same as the return type
+ if (CheckScalarOrVector(&SemaRef, TheCall, getASTContext().BoolTy, 0))
+ return true;
+
+ // Ensure input parameter type is bool
+ ExprResult A = TheCall->getArg(0);
+ QualType ArgTyA = A.get()->getType();
+
+ // return type is the same as the input type
+ TheCall->setType(ArgTyA);
+
+ break;
+ }
case Builtin::BI__builtin_hlsl_all:
case Builtin::BI__builtin_hlsl_any: {
if (SemaRef.checkArgCount(TheCall, 1))
diff --git a/clang/test/CodeGenHLSL/builtins/or.hlsl b/clang/test/CodeGenHLSL/builtins/or.hlsl
new file mode 100644
index 0000000000000..0c21973bda17c
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/or.hlsl
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN: dxil-pc-shadermodel6.3-library %s \
+// RUN: -emit-llvm -O1 -o - | FileCheck %s
+
+//CHECK-LABEL: define noundef i1 @_Z12test_or_boolbb(
+//CHECK-SAME: i1 noundef [[X:%.*]], i1 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+//CHECK-NEXT: [[ENTRY:.*:]]
+//CHECK-NEXT: [[HLSL_OR:%.*]] = or i1 [[x]], [[y]]
+//CHECK-NEXT: ret i1 [[HLSL_OR]]
+//CHECK_NEXT: }
+bool test_or_bool(bool x, bool y)
+{
+ return or(x, y);
+
+}
+
+//CHECK-LABEL: define noundef <2 x i1> @_Z13test_or_bool2Dv2_bS_(
+//CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
+//CHECK-NEXT: [[ENTRY:.*:]]
+//CHECK-NEXT: [[HLSL_OR:%.*]] = or <2 xi1> [[x]], [[y]]
+//CHECK-NEXT: ret <2 x i1> [[HLSL_OR]]
+//CHECK_NEXT: }
+bool2 test_or_bool2(bool2 x, bool2 y)
+{
+ return or(x, y);
+}
+
+//CHECK-LABEL: define noundef <3 x i1> @_Z13test_or_bool3Dv3_bS_(
+//CHECK-SAME: <3 x i1> noundef [[X:%.*]], <3 x i1> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
+//CHECK-NEXT: [[ENTRY:.*:]]
+//CHECK-NEXT: [[HLSL_OR:%.*]] = or <3 xi1> [[x]], [[y]]
+//CHECK-NEXT: ret <3 x i1> [[HLSL_OR]]
+//CHECK_NEXT: }
+bool3 test_or_bool3(bool3 x, bool3 y)
+{
+ return or(x, y);
+}
+
+//CHECK-LABEL: define noundef <4 x i1> @_Z13test_or_bool4Dv4_bS_(
+//CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
+//CHECK-NEXT: [[ENTRY:.*:]]
+//CHECK-NEXT: [[HLSL_OR:%.*]] = or <4 xi1> [[x]], [[y]]
+//CHECK-NEXT: ret <4 x i1> [[HLSL_OR]]
+//CHECK_NEXT: }
+bool4 test_or_bool4(bool4 x, bool4 y)
+{
+ return or(x, y);
+}
+
+//CHECK-LABEL: define noundef i1 @_Z11test_or_intii(
+//CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
+//CHECK-NEXT: [[ENTRY:.*:]]
+//CHECK_NEXT: [[0:%.*]] = or i32 [[y]], [[x]]
+//CHECK-NEXT: [[HLSL_OR:%.*]] = icmp ne i32 [[0]], 0
+//CHECK-NEXT: ret i1 [[HLSL_OR]]
+//CHECK_NEXT: }
+bool test_or_int(int x, int y)
+{
+ return or(x, y);
+}
+
+//CHECK-LABEL: define noundef <4 x i1> @_Z12test_or_int4Dv4_iS_(
+//CHECK-SAME: <4 x i32> noundef [[X:%.*]], <4 x i32> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
+//CHECK-NEXT: [[ENTRY:.*:]]
+//CHECK_NEXT: [[0:%.*]] = or <4 x i32> [[y]], [[x]]
+//CHECK-NEXT: [[HLSL_OR:%.*]] = icmp ne <4 x i32> [[0]], zeroinitializer
+//CHECK-NEXT: ret <4 x i1> [[HLSL_OR]]
+//CHECK_NEXT: }
+bool4 test_or_int4(int4 x, int4 y)
+{
+ return or(x, y);
+}
+
+//CHECK-LABEL: noundef <4 x i1> @_Z14test_or_float4Dv4_fS_(
+//CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[X:%.*]], <4 x float> noundef nofpclass(nan inf) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] {
+//CHECK-NEXT: [[ENTRY:.*:]]
+//CHECK-NEXT: [[TOBOOL:%.*]] = fcmp reassoc nnan ninf nsz arcp afn une <4 x float> [[X]], zeroinitializer
+//CHECK-NEXT: [[TOBOOL1:%.*]] = fcmp reassoc nnan ninf nsz arcp afn une <4 x float> [[Y]], zeroinitializer
+//CHECK-NEXT: [[HLSL_OR:%.*]] = or <4 x i1> [[TOBOOL]], [[TOBOOL1]]
+//CHECK-NEXT: ret <4 x i1> [[HLSL_OR]]
+//CHECK_NEXT: }
+bool4 test_or_float4(float4 x, float4 y)
+{
+ return or(x, y);
+}
\ No newline at end of file
diff --git a/clang/test/SemaHLSL/BuiltIns/and-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/and-errors.hlsl
deleted file mode 100644
index d9721140b9bf9..0000000000000
--- a/clang/test/SemaHLSL/BuiltIns/and-errors.hlsl
+++ /dev/null
@@ -1,22 +0,0 @@
-// RUN: %clang_cc1 -finclude-default-header -triple \
-// RUN: dxil-pc-shadermodel6.3-library %s -O1 -verify
-
-bool test_too_few_arg(bool a) {
- return __builtin_hlsl_and(a);
- // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
-}
-
-bool test_too_many_arg(bool a) {
- return __builtin_hlsl_and(a, a, a);
- // expected-error@-1 {{too many arguments to function call, expected 2, have 3}}
-}
-
-bool2 test_mismatched_args(bool2 a, bool3 b) {
- return __builtin_hlsl_and(a, b);
- // expected-error@-1 {{all arguments to '__builtin_hlsl_and' must have the same type}}
-}
-
-bool test_incorrect_type(int a) {
- return __builtin_hlsl_and(a, a);
- // expected-error@-1{{invalid operand of type 'int' where 'bool' or a vector of such type is required}}
-}
diff --git a/clang/test/SemaHLSL/BuiltIns/logical-operator-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/logical-operator-errors.hlsl
new file mode 100644
index 0000000000000..41bf3c4b2f663
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/logical-operator-errors.hlsl
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -verify -DTEST_FUNC=__builtin_hlsl_or
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -verify -DTEST_FUNC=__builtin_hlsl_and
+
+
+bool test_too_few_arg(bool a)
+{
+ return TEST_FUNC(a);
+ // expected-error@-1 {{too few arguments to function call, expected 2, have 1}}
+}
+
+bool test_too_many_arg(bool a)
+{
+ return TEST_FUNC(a, a, a);
+ // expected-error@-1 {{too many arguments to function call, expected 2, have 3}}
+}
+
+bool2 test_mismatched_args(bool2 a, bool3 b)
+{
+ return TEST_FUNC(a, b);
+ // expected-error@-1 {{all arguments to}}{{.*}}{{must have the same type}}
+}
+
+bool test_incorrect_type(int a)
+{
+ return TEST_FUNC(a, a);
+ // expected-error@-1{{invalid operand of type 'int' where 'bool' or a vector of such type is required}}
+}
\ No newline at end of file
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Congrats on getting your first change out for review! Some notes, mainly around comments, although we probably also want to fix the clang-format issue (if there is one).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please be sure to tag the issue that this is addressing in the PR description (something like "Closes #xxxx".) Or at least make sure that it is linked in the "Development" section.
(Oops, I had two tabs open and confused github and myself)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates.
Please be sure to tag the issue that this is addressing in the PR description (something like "Closes #xxxx".) Or at least make sure that it is linked in the "Development" section.
I won't be clicking Approve because we need approval from someone with more knowledge about this area of the code than I have.
@farzonl maybe? Or he could nominate someone else.
@@ -2305,6 +2305,24 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { | |||
TheCall->setType(ArgTyA); | |||
break; | |||
} | |||
case Builtin::BI__builtin_hlsl_or: { | |||
if (SemaRef.checkArgCount(TheCall, 2)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are doing the same sema checks for the and intrinsic. Delete this whole block and merge the and an or builtins as fall through cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code updated with suggested changes.
@@ -0,0 +1,84 @@ | |||
// RUN: %clang_cc1 -finclude-default-header -triple \ | |||
// RUN: dxil-pc-shadermodel6.3-library %s \ | |||
// RUN: -emit-llvm -O1 -o - | FileCheck %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose you are doing O1 because you want to see short circuiting optimizations? I think this would better to check we are doing thing correctly without any optimizations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test cases updated without any optimization
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sema and codgen test need to be update according to comments.
// or builtins | ||
//===----------------------------------------------------------------------===// | ||
|
||
/// \fn bool or(bool x, bbol y) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// \fn bool or(bool x, bbol y) | |
/// \fn bool or(bool x, bool y) |
//CHECK-NEXT: [[HLSL_OR:%.*]] = or i1 [[X]], [[Y]] | ||
//CHECK-NEXT: ret i1 [[HLSL_OR]] | ||
//CHECK-NEXT: } | ||
bool test_and_scalar(bool x, bool y) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bool test_and_scalar(bool x, bool y) | |
bool test_or_scalar(bool x, bool y) | |
bool2 test_mismatched_args(bool2 a, bool3 b) | ||
{ | ||
return TEST_FUNC(a, b); | ||
// expected-error@-1 {{all arguments to}}{{.*}}{{must have the same type}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This suggestion is almost certainly wrong way to type this out. Just trying to show the idea. Does the .* here capture and
/or
in the error message? If yes, match the possible valid cases with an or regex instead of allowing anything (another point for DAMP being more clear)
// expected-error@-1 {{all arguments to}}{{.*}}{{must have the same type}} | |
// expected-error@-1 {{all arguments to}}{{and|or}}{{must have the same type}} | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should actually be _builtin_hlsl_or
and _builtin_hlsl_and
but the idea is correct.
|
||
//CHECK-LABEL: define noundef <4 x i1> @_Z12test_or_int4Dv4_iS_( | ||
//CHECK-SAME: <4 x i32> noundef [[X:%.*]], <4 x i32> noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { | ||
//CHECK-NEXT: [[ENTRY:.*:]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this line have a stricter match? If not, does it make since to just delete it? .*
is such a broad match that it doesn't provide much value imo
@farzonl looking at the generated IR I'm pretty sure the answer is no but its better to confirm. Does this intrinsic not need DXIL/SPIR-V lowering? Guessing no because it's using stuff that already has lowering rules? |
Your intution is correct. SPIR-V handles the or instruction and for DirectX llvm ir |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@metkarpoonam Congratulations on having your first Pull Request (PR) merged into the LLVM Project! Your changes will be combined with recent changes from other authors, then tested by our build bots. If there is a problem with a build, you may receive a report in an email or a comment on this PR. Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues. How to do this, and the rest of the post-merge process, is covered in detail here. If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of LLVM development. You can fix your changes and open a new PR to merge them again. If you don't get any reports, no action is required from you. Your changes are working as expected, well done! |
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.
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.
completes #125605