Author: Joshua Batista
Date: 2023-07-24T14:03:58-07:00
New Revision: 3a98e73169e1d8e4fbb739462eea62445db1a6c8

URL: 
https://github.com/llvm/llvm-project/commit/3a98e73169e1d8e4fbb739462eea62445db1a6c8
DIFF: 
https://github.com/llvm/llvm-project/commit/3a98e73169e1d8e4fbb739462eea62445db1a6c8.diff

LOG:  clang: Add elementwise pow builtin

Add codegen for llvm pow elementwise builtin
The pow elementwise builtin is necessary for HLSL codegen.
Tests were added to make sure that the expected errors are encountered when 
these functions are given inputs of incompatible types, or too many inputs.
The new builtin is restricted to floating point types only.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D153310

Added: 
    clang/test/Sema/aarch64-sve-vector-pow-ops.c
    clang/test/Sema/riscv-sve-vector-pow-ops.c

Modified: 
    clang/docs/LanguageExtensions.rst
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/Builtins.def
    clang/lib/CodeGen/CGBuiltin.cpp
    clang/lib/Sema/SemaChecking.cpp
    clang/test/CodeGen/builtins-elementwise-math.c
    clang/test/CodeGen/strictfp-elementwise-bulitins.cpp
    clang/test/Sema/builtins-elementwise-math.c
    clang/test/SemaCXX/builtins-elementwise-math.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 6705ee176196cc..1830480b1285d7 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -639,6 +639,7 @@ Unless specified otherwise operation(±0) = ±0 and 
operation(±infinity) = ±in
  T __builtin_elementwise_log(T x)            return the natural logarithm of x 
                               floating point types
  T __builtin_elementwise_log2(T x)           return the base 2 logarithm of x  
                               floating point types
  T __builtin_elementwise_log10(T x)          return the base 10 logarithm of x 
                               floating point types
+ T __builtin_elementwise_pow(T x, T y)       return x raised to the power of y 
                               floating point types
  T __builtin_elementwise_exp(T x)            returns the base-e exponential, 
e^x, of the specified value      floating point types
  T __builtin_elementwise_exp2(T x)           returns the base-2 exponential, 
2^x, of the specified value      floating point types
  T __builtin_elementwise_roundeven(T x)      round x to the nearest integer 
value in floating point format,   floating point types

diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d6cf96bee488d1..4f82edd0d03d14 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -961,6 +961,7 @@ Floating Point Support in Clang
 - Add ``__builtin_elementwise_exp`` builtin for floating point types only.
 - Add ``__builtin_elementwise_exp2`` builtin for floating point types only.
 - Add ``__builtin_set_flt_rounds`` builtin for X86, x86_64, Arm and AArch64 
only.
+- Add ``__builtin_elementwise_pow`` builtin for floating point types only.
 
 AST Matchers
 ------------

diff  --git a/clang/include/clang/Basic/Builtins.def 
b/clang/include/clang/Basic/Builtins.def
index fe00a2f69922a1..6dad8b512bd2df 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -687,6 +687,7 @@ BUILTIN(__builtin_elementwise_floor, "v.", "nct")
 BUILTIN(__builtin_elementwise_log, "v.", "nct")
 BUILTIN(__builtin_elementwise_log2, "v.", "nct")
 BUILTIN(__builtin_elementwise_log10, "v.", "nct")
+BUILTIN(__builtin_elementwise_pow, "v.", "nct")
 BUILTIN(__builtin_elementwise_roundeven, "v.", "nct")
 BUILTIN(__builtin_elementwise_round, "v.", "nct")
 BUILTIN(__builtin_elementwise_rint, "v.", "nct")

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index d5ad35c0c93602..30f5f4e7061c05 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3234,6 +3234,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   case Builtin::BI__builtin_elementwise_log10:
     return RValue::get(
         emitUnaryBuiltin(*this, E, llvm::Intrinsic::log10, "elt.log10"));
+  case Builtin::BI__builtin_elementwise_pow: {
+    return RValue::get(emitBinaryBuiltin(*this, E, llvm::Intrinsic::pow));
+  }
   case Builtin::BI__builtin_elementwise_cos:
     return RValue::get(
         emitUnaryBuiltin(*this, E, llvm::Intrinsic::cos, "elt.cos"));

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 17d9889da85e2d..f8e48728da6647 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2657,6 +2657,22 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
       return ExprError();
     break;
   }
+
+  // These builtins restrict the element type to floating point
+  // types only, and take in two arguments.
+  case Builtin::BI__builtin_elementwise_pow: {
+    if (SemaBuiltinElementwiseMath(TheCall))
+      return ExprError();
+
+    QualType ArgTy = TheCall->getArg(0)->getType();
+    if (checkFPMathBuiltinElementType(*this, TheCall->getArg(0)->getBeginLoc(),
+                                      ArgTy, 1) ||
+        checkFPMathBuiltinElementType(*this, TheCall->getArg(1)->getBeginLoc(),
+                                      ArgTy, 2))
+      return ExprError();
+    break;
+  }
+
   // These builtins restrict the element type to integer
   // types only.
   case Builtin::BI__builtin_elementwise_add_sat:

diff  --git a/clang/test/CodeGen/builtins-elementwise-math.c 
b/clang/test/CodeGen/builtins-elementwise-math.c
index 729fd518c4488d..1087986c434774 100644
--- a/clang/test/CodeGen/builtins-elementwise-math.c
+++ b/clang/test/CodeGen/builtins-elementwise-math.c
@@ -452,6 +452,26 @@ void test_builtin_elementwise_log2(float f1, float f2, 
double d1, double d2,
   vf2 = __builtin_elementwise_log2(vf1);
 }
 
+void test_builtin_elementwise_pow(float f1, float f2, double d1, double d2,
+                                      float4 vf1, float4 vf2) {
+
+  // CHECK-LABEL: define void @test_builtin_elementwise_pow(
+  // CHECK:      [[F1:%.+]] = load float, ptr %f1.addr, align 4
+  // CHECK:      [[F2:%.+]] = load float, ptr %f2.addr, align 4
+  // CHECK-NEXT:  call float @llvm.pow.f32(float [[F1]], float [[F2]])
+  f2 = __builtin_elementwise_pow(f1, f2);
+
+  // CHECK:      [[D1:%.+]] = load double, ptr %d1.addr, align 8
+  // CHECK:      [[D2:%.+]] = load double, ptr %d2.addr, align 8
+  // CHECK-NEXT: call double @llvm.pow.f64(double [[D1]], double [[D2]])
+  d2 = __builtin_elementwise_pow(d1, d2);
+
+  // CHECK:      [[VF1:%.+]] = load <4 x float>, ptr %vf1.addr, align 16
+  // CHECK:      [[VF2:%.+]] = load <4 x float>, ptr %vf2.addr, align 16
+  // CHECK-NEXT: call <4 x float> @llvm.pow.v4f32(<4 x float> [[VF1]], <4 x 
float> [[VF2]])
+  vf2 = __builtin_elementwise_pow(vf1, vf2);
+}
+
 void test_builtin_elementwise_roundeven(float f1, float f2, double d1, double 
d2,
                                         float4 vf1, float4 vf2) {
   // CHECK-LABEL: define void @test_builtin_elementwise_roundeven(

diff  --git a/clang/test/CodeGen/strictfp-elementwise-bulitins.cpp 
b/clang/test/CodeGen/strictfp-elementwise-bulitins.cpp
index 3417d531c92bb3..76110e48ea3509 100644
--- a/clang/test/CodeGen/strictfp-elementwise-bulitins.cpp
+++ b/clang/test/CodeGen/strictfp-elementwise-bulitins.cpp
@@ -217,3 +217,12 @@ float4 strict_elementwise_fma(float4 a, float4 b, float4 
c) {
   return __builtin_elementwise_fma(a, b, c);
 }
 
+// CHECK-LABEL: define dso_local noundef <4 x float> 
@_Z22strict_elementwise_powDv4_fS_
+// CHECK-SAME: (<4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]]) 
local_unnamed_addr #[[ATTR2]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call <4 x float> @llvm.pow.v4f32(<4 x 
float> [[A]], <4 x float> [[B]]) #[[ATTR4]]
+// CHECK-NEXT:    ret <4 x float> [[TMP0]]
+//
+float4 strict_elementwise_pow(float4 a, float4 b) {
+  return __builtin_elementwise_pow(a, b);
+}

diff  --git a/clang/test/Sema/aarch64-sve-vector-pow-ops.c 
b/clang/test/Sema/aarch64-sve-vector-pow-ops.c
new file mode 100644
index 00000000000000..1024cdc2517d07
--- /dev/null
+++ b/clang/test/Sema/aarch64-sve-vector-pow-ops.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple aarch64 -target-feature +f -target-feature +d \
+// RUN:   -target-feature +v -target-feature +zfh  -target-feature +sve 
-target-feature +experimental-zvfh \
+// RUN:   -disable-O0-optnone -o - -fsyntax-only %s -verify 
+// REQUIRES: aarch64-registered-target
+
+#include <arm_sve.h>
+
+svfloat32_t test_pow_vv_i8mf8(svfloat32_t v) {
+
+  return __builtin_elementwise_pow(v, v);
+  // expected-error@-1 {{1st argument must be a vector, integer or floating 
point type}}
+}

diff  --git a/clang/test/Sema/builtins-elementwise-math.c 
b/clang/test/Sema/builtins-elementwise-math.c
index c23367df110ce9..5aad056c4de409 100644
--- a/clang/test/Sema/builtins-elementwise-math.c
+++ b/clang/test/Sema/builtins-elementwise-math.c
@@ -438,6 +438,31 @@ void test_builtin_elementwise_log2(int i, float f, double 
d, float4 v, int3 iv,
   // expected-error@-1 {{1st argument must be a floating point type (was 
'unsigned4' (vector of 4 'unsigned int' values))}}
 }
 
+void test_builtin_elementwise_pow(int i, short s, double d, float4 v, int3 iv, 
unsigned3 uv, int *p) {
+  i = __builtin_elementwise_pow(p, d);
+  // expected-error@-1 {{arguments are of 
diff erent types ('int *' vs 'double')}}
+
+  struct Foo foo = __builtin_elementwise_pow(i, i);
+  // expected-error@-1 {{1st argument must be a floating point type (was 
'int')}}
+
+  i = __builtin_elementwise_pow(i);
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 
1}}
+
+  i = __builtin_elementwise_pow();
+  // expected-error@-1 {{too few arguments to function call, expected 2, have 
0}}
+
+  i = __builtin_elementwise_pow(i, i, i);
+  // expected-error@-1 {{too many arguments to function call, expected 2, have 
3}}
+
+  i = __builtin_elementwise_pow(v, iv);
+  // expected-error@-1 {{arguments are of 
diff erent types ('float4' (vector of 4 'float' values) vs 'int3' (vector of 3 
'int' values))}}
+
+  i = __builtin_elementwise_pow(uv, iv);
+  // expected-error@-1 {{arguments are of 
diff erent types ('unsigned3' (vector of 3 'unsigned int' values) vs 'int3' 
(vector of 3 'int' values))}}
+  
+}
+
+
 void test_builtin_elementwise_roundeven(int i, float f, double d, float4 v, 
int3 iv, unsigned u, unsigned4 uv) {
 
   struct Foo s = __builtin_elementwise_roundeven(f);

diff  --git a/clang/test/Sema/riscv-sve-vector-pow-ops.c 
b/clang/test/Sema/riscv-sve-vector-pow-ops.c
new file mode 100644
index 00000000000000..78efb4b549f801
--- /dev/null
+++ b/clang/test/Sema/riscv-sve-vector-pow-ops.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d \
+// RUN:   -target-feature +v -target-feature +zfh -target-feature 
+experimental-zvfh \
+// RUN:   -disable-O0-optnone -o - -fsyntax-only %s -verify 
+// REQUIRES: riscv-registered-target
+
+#include <riscv_vector.h>
+
+
+vfloat32mf2_t test_pow_vv_i8mf8(vfloat32mf2_t v) {
+
+  return __builtin_elementwise_pow(v, v);
+  // expected-error@-1 {{1st argument must be a vector, integer or floating 
point type}}
+}

diff  --git a/clang/test/SemaCXX/builtins-elementwise-math.cpp 
b/clang/test/SemaCXX/builtins-elementwise-math.cpp
index 9a0e622f7bf973..492497aa33658a 100644
--- a/clang/test/SemaCXX/builtins-elementwise-math.cpp
+++ b/clang/test/SemaCXX/builtins-elementwise-math.cpp
@@ -198,3 +198,11 @@ void test_builtin_elementwise_fma() {
   static_assert(!is_const<decltype(__builtin_elementwise_fma(b, a, 
c))>::value);
   static_assert(!is_const<decltype(__builtin_elementwise_fma(c, c, 
c))>::value);
 }
+
+void test_builtin_elementwise_pow() {
+  const double a = 2;
+  double b = 1;
+  static_assert(!is_const<decltype(__builtin_elementwise_pow(a, b))>::value);
+  static_assert(!is_const<decltype(__builtin_elementwise_pow(b, a))>::value);
+  static_assert(!is_const<decltype(__builtin_elementwise_pow(a, a))>::value);
+}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to