[clang] [clang] constexpr built-in abs function. (PR #112539)

via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 18 02:22:54 PDT 2024


https://github.com/c8ef updated https://github.com/llvm/llvm-project/pull/112539

>From dfa1585af3f080987cbd15830c45c34bfecc1fca Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Wed, 16 Oct 2024 01:18:13 +0000
Subject: [PATCH 01/11] implement constexpr builtin {l}abs

---
 clang/include/clang/Basic/Builtins.td         |  1 +
 clang/lib/AST/ExprConstant.cpp                | 11 +++++++++++
 clang/test/AST/ByteCode/builtin-functions.cpp |  9 +++++++++
 3 files changed, 21 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index bda8a48be92bda..e1b4d5b1fdc0a5 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -2714,6 +2714,7 @@ def Abs : IntMathTemplate, LibBuiltin<"stdlib.h"> {
   let Attributes = [NoThrow, Const];
   let Prototype = "T(T)";
   let AddBuiltinPrefixedAlias = 1;
+  let OnlyBuiltinPrefixedAliasIsConstexpr = 1;
 }
 
 def Calloc : LibBuiltin<"stdlib.h"> {
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 52a7f5778ce6d2..69539a7f03feba 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -13055,6 +13055,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
     return Success(Val.popcount() % 2, E);
   }
 
+  case Builtin::BI__builtin_abs:
+  case Builtin::BI__builtin_labs:
+  case Builtin::BI__builtin_llabs: {
+    APSInt Val;
+    if (!EvaluateInteger(E->getArg(0), Val, Info))
+      return false;
+    if (Val.isNegative())
+      Val.negate();
+    return Success(Val, E);
+  }
+
   case Builtin::BI__builtin_popcount:
   case Builtin::BI__builtin_popcountl:
   case Builtin::BI__builtin_popcountll:
diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp
index 450ff5671314db..46e5b0579bd575 100644
--- a/clang/test/AST/ByteCode/builtin-functions.cpp
+++ b/clang/test/AST/ByteCode/builtin-functions.cpp
@@ -265,6 +265,15 @@ namespace fpclassify {
   char classify_subnorm [__builtin_fpclassify(-1, -1, -1, +1, -1, 1.0e-38f)];
 }
 
+namespace abs {
+static_assert(__builtin_abs(14) == 14, "");
+static_assert(__builtin_labs(14L) == 14L, "");
+static_assert(__builtin_llabs(14LL) == 14LL, "");
+static_assert(__builtin_abs(-14) == 14, "");
+static_assert(__builtin_labs(-14L) == 14L, "");
+static_assert(__builtin_llabs(-14LL) == 14LL, "");
+} // namespace abs
+
 namespace fabs {
   static_assert(__builtin_fabs(-14.0) == 14.0, "");
 }

>From 52e1d070b392ea4651acf5f7f984a1defb035459 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Wed, 16 Oct 2024 12:32:37 +0800
Subject: [PATCH 02/11] Update InterpBuiltin.cpp

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 65c7b4e5306d72..1e1a75e5514aec 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -563,6 +563,17 @@ static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC,
   return true;
 }
 
+static bool interp__builtin_abs(InterpState &S, CodePtr OpPC,
+                                const InterpFrame *Frame, const Function *Func,
+                                const CallExpr *Call) {
+  PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
+  APSInt Val = peekToAPSInt(S.Stk, ArgT);
+  if (Val.isNegative())
+    Val.negate();
+  pushInteger(S, Val, Call->getType());
+  return true;
+}
+
 static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC,
                                      const InterpFrame *Frame,
                                      const Function *Func,
@@ -1808,6 +1819,13 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
       return false;
     break;
 
+  case Builtin::BI__builtin_abs:
+  case Builtin::BI__builtin_labs:
+  case Builtin::BI__builtin_llabs:
+  if (!interp__builtin_abs(S, OpPC, Frame, F, Call))
+    return false;
+  break;
+
   case Builtin::BI__builtin_popcount:
   case Builtin::BI__builtin_popcountl:
   case Builtin::BI__builtin_popcountll:

>From 227193529178a1c1484c0da42a06289a26c75114 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Wed, 16 Oct 2024 12:33:29 +0800
Subject: [PATCH 03/11] Update ExprConstant.cpp

---
 clang/lib/AST/ExprConstant.cpp | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 69539a7f03feba..52a7f5778ce6d2 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -13055,17 +13055,6 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
     return Success(Val.popcount() % 2, E);
   }
 
-  case Builtin::BI__builtin_abs:
-  case Builtin::BI__builtin_labs:
-  case Builtin::BI__builtin_llabs: {
-    APSInt Val;
-    if (!EvaluateInteger(E->getArg(0), Val, Info))
-      return false;
-    if (Val.isNegative())
-      Val.negate();
-    return Success(Val, E);
-  }
-
   case Builtin::BI__builtin_popcount:
   case Builtin::BI__builtin_popcountl:
   case Builtin::BI__builtin_popcountll:

>From 5f45e1feba15266662ce171366c0450c86b58b64 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Wed, 16 Oct 2024 12:38:09 +0800
Subject: [PATCH 04/11] Update InterpBuiltin.cpp

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 1e1a75e5514aec..8a27658d7fb6a4 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -1822,9 +1822,9 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   case Builtin::BI__builtin_abs:
   case Builtin::BI__builtin_labs:
   case Builtin::BI__builtin_llabs:
-  if (!interp__builtin_abs(S, OpPC, Frame, F, Call))
-    return false;
-  break;
+    if (!interp__builtin_abs(S, OpPC, Frame, F, Call))
+      return false;
+    break;
 
   case Builtin::BI__builtin_popcount:
   case Builtin::BI__builtin_popcountl:

>From 05b6cd41661c347ef9932dcb651851ef95e67379 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Wed, 16 Oct 2024 13:55:34 +0800
Subject: [PATCH 05/11] Update ExprConstant.cpp

---
 clang/lib/AST/ExprConstant.cpp | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 52a7f5778ce6d2..69539a7f03feba 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -13055,6 +13055,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
     return Success(Val.popcount() % 2, E);
   }
 
+  case Builtin::BI__builtin_abs:
+  case Builtin::BI__builtin_labs:
+  case Builtin::BI__builtin_llabs: {
+    APSInt Val;
+    if (!EvaluateInteger(E->getArg(0), Val, Info))
+      return false;
+    if (Val.isNegative())
+      Val.negate();
+    return Success(Val, E);
+  }
+
   case Builtin::BI__builtin_popcount:
   case Builtin::BI__builtin_popcountl:
   case Builtin::BI__builtin_popcountll:

>From 12e545f87482a2965804057eda3821e5946be4b8 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Wed, 16 Oct 2024 18:10:48 +0800
Subject: [PATCH 06/11] Update ExprConstant.cpp

---
 clang/lib/AST/ExprConstant.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 69539a7f03feba..256bc7454e5f46 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -13061,6 +13061,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
     APSInt Val;
     if (!EvaluateInteger(E->getArg(0), Val, Info))
       return false;
+    if (Val == APSInt::getSignedMinValue(Val.getBitWidth()))
+      return false;
     if (Val.isNegative())
       Val.negate();
     return Success(Val, E);

>From 0adef1074cc3982fdef4166b4913fd57858ea09d Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Wed, 16 Oct 2024 18:23:36 +0800
Subject: [PATCH 07/11] Update ExprConstant.cpp

---
 clang/lib/AST/ExprConstant.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 256bc7454e5f46..d1d6790e152527 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -13061,7 +13061,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
     APSInt Val;
     if (!EvaluateInteger(E->getArg(0), Val, Info))
       return false;
-    if (Val == APSInt::getSignedMinValue(Val.getBitWidth()))
+    if (Val == APSInt(APSInt::getSignedMinValue(Val.getBitWidth()), false))
       return false;
     if (Val.isNegative())
       Val.negate();

>From 7881253f5e1d4936473ac158d00156007919f8f1 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Wed, 16 Oct 2024 13:13:17 +0000
Subject: [PATCH 08/11] abs

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp      |  2 ++
 clang/test/AST/ByteCode/builtin-functions.cpp |  4 ++--
 clang/test/CodeGenCXX/builtins.cpp            | 14 ++++++--------
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 8a27658d7fb6a4..b4ab744ea14104 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -568,6 +568,8 @@ static bool interp__builtin_abs(InterpState &S, CodePtr OpPC,
                                 const CallExpr *Call) {
   PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
   APSInt Val = peekToAPSInt(S.Stk, ArgT);
+  if (Val == APSInt(APSInt::getSignedMinValue(Val.getBitWidth()), false))
+    return false;
   if (Val.isNegative())
     Val.negate();
   pushInteger(S, Val, Call->getType());
diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp
index 46e5b0579bd575..1ec9b5fdcbd228 100644
--- a/clang/test/AST/ByteCode/builtin-functions.cpp
+++ b/clang/test/AST/ByteCode/builtin-functions.cpp
@@ -270,8 +270,8 @@ static_assert(__builtin_abs(14) == 14, "");
 static_assert(__builtin_labs(14L) == 14L, "");
 static_assert(__builtin_llabs(14LL) == 14LL, "");
 static_assert(__builtin_abs(-14) == 14, "");
-static_assert(__builtin_labs(-14L) == 14L, "");
-static_assert(__builtin_llabs(-14LL) == 14LL, "");
+static_assert(__builtin_labs(-0x14L) == 0x14L, "");
+static_assert(__builtin_llabs(-0x141414141414LL) == 0x141414141414LL, "");
 } // namespace abs
 
 namespace fabs {
diff --git a/clang/test/CodeGenCXX/builtins.cpp b/clang/test/CodeGenCXX/builtins.cpp
index 90265186fb3d8c..37f9491d12d04b 100644
--- a/clang/test/CodeGenCXX/builtins.cpp
+++ b/clang/test/CodeGenCXX/builtins.cpp
@@ -14,6 +14,12 @@ int o = X::__builtin_fabs(-2.0);
 long p = X::__builtin_fabsf(-3.0f);
 // CHECK: @p ={{.*}} global i64 3, align 8
 
+int x = __builtin_abs(-2);
+// CHECK: @x ={{.*}} global i32 2, align 4
+
+long y = __builtin_abs(-2l);
+// CHECK: @y ={{.*}} global i64 2, align 8
+
 // PR8839
 extern "C" char memmove();
 
@@ -52,14 +58,6 @@ extern "C" int __builtin_abs(int); // #1
 long __builtin_abs(long);          // #2
 extern "C" int __builtin_abs(int); // #3
 
-int x = __builtin_abs(-2);
-// CHECK:      [[X:%.+]] = call i32 @llvm.abs.i32(i32 -2, i1 true)
-// CHECK-NEXT: store i32 [[X]], ptr @x, align 4
-
-long y = __builtin_abs(-2l);
-// CHECK:  [[Y:%.+]] = call noundef i64 @_Z13__builtin_absl(i64 noundef -2)
-// CHECK:  store i64 [[Y]], ptr @y, align 8
-
 extern const char char_memchr_arg[32];
 char *memchr_result = __builtin_char_memchr(char_memchr_arg, 123, 32);
 // CHECK: call ptr @memchr(ptr noundef @char_memchr_arg, i32 noundef 123, i64 noundef 32)

>From 7efd267eed67beef6b556e6dc55dcdcb53d4101b Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Wed, 16 Oct 2024 14:35:35 +0000
Subject: [PATCH 09/11] add more test

---
 clang/test/Sema/constant-builtins-2.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/clang/test/Sema/constant-builtins-2.c b/clang/test/Sema/constant-builtins-2.c
index da2264500d7680..e465a3c5f0ad86 100644
--- a/clang/test/Sema/constant-builtins-2.c
+++ b/clang/test/Sema/constant-builtins-2.c
@@ -35,7 +35,7 @@ long double  g11 = __builtin_nansl("");
 __float128   g11_2 = __builtin_nansf128("");
 #endif
 
-//int          g12 = __builtin_abs(-12);
+int g12 = __builtin_abs(-12);
 
 double       g13 = __builtin_fabs(-12.);
 double       g13_0 = __builtin_fabs(-0.);
@@ -456,6 +456,17 @@ char clrsb9[__builtin_clrsb(1 << (BITSIZE(int) - 1)) == 0 ? 1 : -1];
 char clrsb10[__builtin_clrsb(~(1 << (BITSIZE(int) - 1))) == 0 ? 1 : -1];
 char clrsb11[__builtin_clrsb(0xf) == BITSIZE(int) - 5 ? 1 : -1];
 char clrsb12[__builtin_clrsb(~0x1f) == BITSIZE(int) - 6 ? 1 : -1];
+
+char abs1[__builtin_abs(-12)];
+char abs2[__builtin_labs(-12L)];
+char abs3[__builtin_llabs(-12LL)];
+int abs4 = __builtin_abs(1 << (BITSIZE(int) - 1)); // expected-error {{not a compile-time constant}}
+char abs5[__builtin_abs((1 << (BITSIZE(int) - 1)) + 1)];
+long abs6 = __builtin_labs(1L << (BITSIZE(long) - 1)); // expected-error {{not a compile-time constant}}
+long abs7 = __builtin_labs((1L << (BITSIZE(long) - 1)) + 1);
+long long abs8 = __builtin_llabs(1LL << (BITSIZE(long long) - 1)); // expected-error {{not a compile-time constant}}
+long long abs9 = __builtin_llabs((1LL << (BITSIZE(long long) - 1)) + 1);
+
 #undef BITSIZE
 
 // GCC misc stuff

>From 5a4dcbddcb36e1496c67e4e391e302d5ec4a471b Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Thu, 17 Oct 2024 11:48:19 +0000
Subject: [PATCH 10/11] address review comments

---
 clang/docs/ReleaseNotes.rst                   |  1 +
 clang/lib/AST/ByteCode/InterpBuiltin.cpp      |  3 ++-
 clang/lib/AST/ExprConstant.cpp                |  3 ++-
 clang/test/AST/ByteCode/builtin-functions.cpp | 12 ++++++------
 4 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 817e3abef8d566..08583a5a16312b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -252,6 +252,7 @@ Non-comprehensive list of changes in this release
   ``__builtin_signbit`` can now be used in constant expressions.
 - Plugins can now define custom attributes that apply to statements
   as well as declarations.
+- ``__builtin_abs`` function can now be used in constant expressions.
 
 New Compiler Flags
 ------------------
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index b4ab744ea14104..d4a8e6c2035ee5 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -568,7 +568,8 @@ static bool interp__builtin_abs(InterpState &S, CodePtr OpPC,
                                 const CallExpr *Call) {
   PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
   APSInt Val = peekToAPSInt(S.Stk, ArgT);
-  if (Val == APSInt(APSInt::getSignedMinValue(Val.getBitWidth()), false))
+  if (Val ==
+      APSInt(APInt::getSignedMinValue(Val.getBitWidth()), /*IsUnsigned=*/false))
     return false;
   if (Val.isNegative())
     Val.negate();
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index d1d6790e152527..dcd07e3496001e 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -13061,7 +13061,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
     APSInt Val;
     if (!EvaluateInteger(E->getArg(0), Val, Info))
       return false;
-    if (Val == APSInt(APSInt::getSignedMinValue(Val.getBitWidth()), false))
+    if (Val == APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
+                      /*IsUnsigned=*/false))
       return false;
     if (Val.isNegative())
       Val.negate();
diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp
index 1ec9b5fdcbd228..a616400f7b31e0 100644
--- a/clang/test/AST/ByteCode/builtin-functions.cpp
+++ b/clang/test/AST/ByteCode/builtin-functions.cpp
@@ -266,12 +266,12 @@ namespace fpclassify {
 }
 
 namespace abs {
-static_assert(__builtin_abs(14) == 14, "");
-static_assert(__builtin_labs(14L) == 14L, "");
-static_assert(__builtin_llabs(14LL) == 14LL, "");
-static_assert(__builtin_abs(-14) == 14, "");
-static_assert(__builtin_labs(-0x14L) == 0x14L, "");
-static_assert(__builtin_llabs(-0x141414141414LL) == 0x141414141414LL, "");
+  static_assert(__builtin_abs(14) == 14, "");
+  static_assert(__builtin_labs(14L) == 14L, "");
+  static_assert(__builtin_llabs(14LL) == 14LL, "");
+  static_assert(__builtin_abs(-14) == 14, "");
+  static_assert(__builtin_labs(-0x14L) == 0x14L, "");
+  static_assert(__builtin_llabs(-0x141414141414LL) == 0x141414141414LL, "");
 } // namespace abs
 
 namespace fabs {

>From 89a29c51bb588656823959f1ef9a69342b0fbd4f Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Thu, 17 Oct 2024 14:52:39 +0000
Subject: [PATCH 11/11] add test

---
 clang/test/AST/ByteCode/builtin-functions.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp
index a616400f7b31e0..b5d334178f8213 100644
--- a/clang/test/AST/ByteCode/builtin-functions.cpp
+++ b/clang/test/AST/ByteCode/builtin-functions.cpp
@@ -272,6 +272,11 @@ namespace abs {
   static_assert(__builtin_abs(-14) == 14, "");
   static_assert(__builtin_labs(-0x14L) == 0x14L, "");
   static_assert(__builtin_llabs(-0x141414141414LL) == 0x141414141414LL, "");
+#define BITSIZE(x) (sizeof(x) * 8)
+  constexpr int abs4 = __builtin_abs(1 << (BITSIZE(int) - 1)); // both-error {{must be initialized by a constant expression}}
+  constexpr long abs6 = __builtin_labs(1L << (BITSIZE(long) - 1)); // both-error {{must be initialized by a constant expression}}
+  constexpr long long abs8 = __builtin_llabs(1LL << (BITSIZE(long long) - 1)); // both-error {{must be initialized by a constant expression}}
+#undef BITSIZE
 } // namespace abs
 
 namespace fabs {



More information about the cfe-commits mailing list