[clang] 3a98e73 - clang: Add elementwise pow builtin

Joshua Batista via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 24 14:04:09 PDT 2023


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 at -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 at -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 at -1 {{arguments are of 
diff erent types ('int *' vs 'double')}}
+
+  struct Foo foo = __builtin_elementwise_pow(i, i);
+  // expected-error at -1 {{1st argument must be a floating point type (was 'int')}}
+
+  i = __builtin_elementwise_pow(i);
+  // expected-error at -1 {{too few arguments to function call, expected 2, have 1}}
+
+  i = __builtin_elementwise_pow();
+  // expected-error at -1 {{too few arguments to function call, expected 2, have 0}}
+
+  i = __builtin_elementwise_pow(i, i, i);
+  // expected-error at -1 {{too many arguments to function call, expected 2, have 3}}
+
+  i = __builtin_elementwise_pow(v, iv);
+  // expected-error at -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 at -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 at -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);
+}


        


More information about the cfe-commits mailing list