[clang] [clang][Interp] Implement builtin_expect (PR #69713)

2023-12-08 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/69713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement builtin_expect (PR #69713)

2023-11-14 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/69713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement builtin_expect (PR #69713)

2023-11-17 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/69713

>From e11a956d0389b1c0ed4ed54a908c3498dba2aba7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 20 Oct 2023 14:16:22 +0200
Subject: [PATCH] [clang][Interp] Implement builtin_expect

---
 clang/lib/AST/Interp/InterpBuiltin.cpp| 52 +++
 clang/test/AST/Interp/builtin-functions.cpp   |  8 +++
 .../Sema/builtin-expect-with-probability.cpp  |  1 +
 3 files changed, 61 insertions(+)

diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index bb3e13599b01d4e..2cfd19a02c0c33c 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -33,6 +33,19 @@ PrimType getIntPrimType(const InterpState &S) {
   llvm_unreachable("Int isn't 16 or 32 bit?");
 }
 
+PrimType getLongPrimType(const InterpState &S) {
+  const TargetInfo &TI = S.getCtx().getTargetInfo();
+  unsigned LongWidth = TI.getLongWidth();
+
+  if (LongWidth == 64)
+return PT_Sint64;
+  else if (LongWidth == 32)
+return PT_Sint32;
+  else if (LongWidth == 16)
+return PT_Sint16;
+  llvm_unreachable("long isn't 16, 32 or 64 bit?");
+}
+
 /// Peek an integer value from the stack into an APSInt.
 static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset = 0) {
   if (Offset == 0)
@@ -109,6 +122,19 @@ static void pushAPSInt(InterpState &S, const APSInt &Val) {
   }
 }
 
+/// Pushes \p Val to the stack, as a target-dependent 'long'.
+static void pushLong(InterpState &S, int64_t Val) {
+  PrimType LongType = getLongPrimType(S);
+  if (LongType == PT_Sint64)
+S.Stk.push>(Integral<64, true>::from(Val));
+  else if (LongType == PT_Sint32)
+S.Stk.push>(Integral<32, true>::from(Val));
+  else if (LongType == PT_Sint16)
+S.Stk.push>(Integral<16, true>::from(Val));
+  else
+llvm_unreachable("Long isn't 16, 32 or 64 bit?");
+}
+
 static void pushSizeT(InterpState &S, uint64_t Val) {
   const TargetInfo &TI = S.getCtx().getTargetInfo();
   unsigned SizeTWidth = TI.getTypeWidth(TI.getSizeType());
@@ -517,6 +543,26 @@ static bool interp__builtin_bitreverse(InterpState &S, 
CodePtr OpPC,
   return true;
 }
 
+// __builtin_expect(long, long)
+// __builtin_expect_with_probability(long, long, double)
+static bool interp__builtin_expect(InterpState &S, CodePtr OpPC,
+   const InterpFrame *Frame,
+   const Function *Func, const CallExpr *Call) 
{
+  // The return value is simply the value of the first parameter.
+  // We ignore the probability.
+  unsigned NumArgs = Call->getNumArgs();
+  assert(NumArgs == 2 || NumArgs == 3);
+
+  PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
+  unsigned Offset = align(primSize(getLongPrimType(S))) * 2;
+  if (NumArgs == 3)
+Offset += align(primSize(PT_Float));
+
+  APSInt Val = peekToAPSInt(S.Stk, ArgT, Offset);
+  pushLong(S, Val.getSExtValue());
+  return true;
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
@@ -681,6 +727,12 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
Function *F,
   return false;
 break;
 
+  case Builtin::BI__builtin_expect:
+  case Builtin::BI__builtin_expect_with_probability:
+if (!interp__builtin_expect(S, OpPC, Frame, F, Call))
+  return false;
+break;
+
   default:
 return false;
   }
diff --git a/clang/test/AST/Interp/builtin-functions.cpp 
b/clang/test/AST/Interp/builtin-functions.cpp
index 0726dab37cb4eb0..35a1f9a75092a05 100644
--- a/clang/test/AST/Interp/builtin-functions.cpp
+++ b/clang/test/AST/Interp/builtin-functions.cpp
@@ -331,3 +331,11 @@ namespace bitreverse {
   char bitreverse3[__builtin_bitreverse32(0x12345678) == 0x1E6A2C48 ? 1 : -1];
   char bitreverse4[__builtin_bitreverse64(0x0123456789ABCDEFULL) == 
0xF7B3D591E6A2C480 ? 1 : -1];
 }
+
+namespace expect {
+  constexpr int a() {
+return 12;
+  }
+  static_assert(__builtin_expect(a(),1) == 12, "");
+  static_assert(__builtin_expect_with_probability(a(), 1, 1.0) == 12, "");
+}
diff --git a/clang/test/Sema/builtin-expect-with-probability.cpp 
b/clang/test/Sema/builtin-expect-with-probability.cpp
index 2b72c7b27ae93e8..c55cde84b254834 100644
--- a/clang/test/Sema/builtin-expect-with-probability.cpp
+++ b/clang/test/Sema/builtin-expect-with-probability.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify 
-fexperimental-new-constant-interpreter %s
 
 __attribute__((noreturn)) extern void bar();
 

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


[clang] [clang][Interp] Implement builtin_expect (PR #69713)

2023-11-21 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/69713

>From 64dbeb52f05dd9c5b9559ed3de571cb87959f63e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 20 Oct 2023 14:16:22 +0200
Subject: [PATCH] [clang][Interp] Implement builtin_expect

---
 clang/lib/AST/Interp/InterpBuiltin.cpp| 52 +++
 clang/test/AST/Interp/builtin-functions.cpp   |  8 +++
 .../Sema/builtin-expect-with-probability.cpp  |  1 +
 3 files changed, 61 insertions(+)

diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 9cf206ecc212adb..4384ace6b6be5e4 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -34,6 +34,19 @@ PrimType getIntPrimType(const InterpState &S) {
   llvm_unreachable("Int isn't 16 or 32 bit?");
 }
 
+PrimType getLongPrimType(const InterpState &S) {
+  const TargetInfo &TI = S.getCtx().getTargetInfo();
+  unsigned LongWidth = TI.getLongWidth();
+
+  if (LongWidth == 64)
+return PT_Sint64;
+  else if (LongWidth == 32)
+return PT_Sint32;
+  else if (LongWidth == 16)
+return PT_Sint16;
+  llvm_unreachable("long isn't 16, 32 or 64 bit?");
+}
+
 /// Peek an integer value from the stack into an APSInt.
 static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset = 0) {
   if (Offset == 0)
@@ -110,6 +123,19 @@ static void pushAPSInt(InterpState &S, const APSInt &Val) {
   }
 }
 
+/// Pushes \p Val to the stack, as a target-dependent 'long'.
+static void pushLong(InterpState &S, int64_t Val) {
+  PrimType LongType = getLongPrimType(S);
+  if (LongType == PT_Sint64)
+S.Stk.push>(Integral<64, true>::from(Val));
+  else if (LongType == PT_Sint32)
+S.Stk.push>(Integral<32, true>::from(Val));
+  else if (LongType == PT_Sint16)
+S.Stk.push>(Integral<16, true>::from(Val));
+  else
+llvm_unreachable("Long isn't 16, 32 or 64 bit?");
+}
+
 static void pushSizeT(InterpState &S, uint64_t Val) {
   const TargetInfo &TI = S.getCtx().getTargetInfo();
   unsigned SizeTWidth = TI.getTypeWidth(TI.getSizeType());
@@ -533,6 +559,26 @@ static bool interp__builtin_classify_type(InterpState &S, 
CodePtr OpPC,
   return true;
 }
 
+// __builtin_expect(long, long)
+// __builtin_expect_with_probability(long, long, double)
+static bool interp__builtin_expect(InterpState &S, CodePtr OpPC,
+   const InterpFrame *Frame,
+   const Function *Func, const CallExpr *Call) 
{
+  // The return value is simply the value of the first parameter.
+  // We ignore the probability.
+  unsigned NumArgs = Call->getNumArgs();
+  assert(NumArgs == 2 || NumArgs == 3);
+
+  PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
+  unsigned Offset = align(primSize(getLongPrimType(S))) * 2;
+  if (NumArgs == 3)
+Offset += align(primSize(PT_Float));
+
+  APSInt Val = peekToAPSInt(S.Stk, ArgT, Offset);
+  pushLong(S, Val.getSExtValue());
+  return true;
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
@@ -702,6 +748,12 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
Function *F,
   return false;
 break;
 
+  case Builtin::BI__builtin_expect:
+  case Builtin::BI__builtin_expect_with_probability:
+if (!interp__builtin_expect(S, OpPC, Frame, F, Call))
+  return false;
+break;
+
   default:
 return false;
   }
diff --git a/clang/test/AST/Interp/builtin-functions.cpp 
b/clang/test/AST/Interp/builtin-functions.cpp
index 0726dab37cb4eb0..35a1f9a75092a05 100644
--- a/clang/test/AST/Interp/builtin-functions.cpp
+++ b/clang/test/AST/Interp/builtin-functions.cpp
@@ -331,3 +331,11 @@ namespace bitreverse {
   char bitreverse3[__builtin_bitreverse32(0x12345678) == 0x1E6A2C48 ? 1 : -1];
   char bitreverse4[__builtin_bitreverse64(0x0123456789ABCDEFULL) == 
0xF7B3D591E6A2C480 ? 1 : -1];
 }
+
+namespace expect {
+  constexpr int a() {
+return 12;
+  }
+  static_assert(__builtin_expect(a(),1) == 12, "");
+  static_assert(__builtin_expect_with_probability(a(), 1, 1.0) == 12, "");
+}
diff --git a/clang/test/Sema/builtin-expect-with-probability.cpp 
b/clang/test/Sema/builtin-expect-with-probability.cpp
index 2b72c7b27ae93e8..c55cde84b254834 100644
--- a/clang/test/Sema/builtin-expect-with-probability.cpp
+++ b/clang/test/Sema/builtin-expect-with-probability.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify 
-fexperimental-new-constant-interpreter %s
 
 __attribute__((noreturn)) extern void bar();
 

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


[clang] [clang][Interp] Implement builtin_expect (PR #69713)

2023-11-03 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/69713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement builtin_expect (PR #69713)

2023-11-09 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/69713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement builtin_expect (PR #69713)

2023-10-28 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/69713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement builtin_expect (PR #69713)

2023-10-20 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr edited 
https://github.com/llvm/llvm-project/pull/69713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement builtin_expect (PR #69713)

2023-10-21 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/69713

>From 1d60343ec3acb89764ab56a7035e1d7355e741ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 20 Oct 2023 14:16:22 +0200
Subject: [PATCH] [clang][Interp] Implement builtin_expect

---
 clang/lib/AST/Interp/InterpBuiltin.cpp| 64 +++
 clang/test/AST/Interp/builtin-functions.cpp   |  8 +++
 .../Sema/builtin-expect-with-probability.cpp  |  1 +
 3 files changed, 73 insertions(+)

diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 7552c1b88cff60c..48678b468e82ed5 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -33,6 +33,19 @@ PrimType getIntPrimType(const InterpState &S) {
   llvm_unreachable("Int isn't 16 or 32 bit?");
 }
 
+PrimType getLongPrimType(const InterpState &S) {
+  const TargetInfo &TI = S.getCtx().getTargetInfo();
+  unsigned LongWidth = TI.getLongWidth();
+
+  if (LongWidth == 64)
+return PT_Sint64;
+  else if (LongWidth == 32)
+return PT_Sint32;
+  else if (LongWidth == 16)
+return PT_Sint16;
+  llvm_unreachable("long isn't 16, 32 or 64 bit?");
+}
+
 /// Peek an integer value from the stack into an APSInt.
 static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset = 0) {
   if (Offset == 0)
@@ -59,6 +72,19 @@ static void pushInt(InterpState &S, int32_t Val) {
 llvm_unreachable("Int isn't 16 or 32 bit?");
 }
 
+/// Pushes \p Val to the stack, as a target-dependent 'long'.
+static void pushLong(InterpState &S, int64_t Val) {
+  PrimType LongType = getLongPrimType(S);
+  if (LongType == PT_Sint64)
+S.Stk.push>(Integral<64, true>::from(Val));
+  else if (LongType == PT_Sint32)
+S.Stk.push>(Integral<32, true>::from(Val));
+  else if (LongType == PT_Sint16)
+S.Stk.push>(Integral<16, true>::from(Val));
+  else
+llvm_unreachable("Long isn't 16, 32 or 64 bit?");
+}
+
 static bool retInt(InterpState &S, CodePtr OpPC, APValue &Result) {
   PrimType IntType = getIntPrimType(S);
   if (IntType == PT_Sint32)
@@ -68,6 +94,17 @@ static bool retInt(InterpState &S, CodePtr OpPC, APValue 
&Result) {
   llvm_unreachable("Int isn't 16 or 32 bit?");
 }
 
+static bool retLong(InterpState &S, CodePtr OpPC, APValue &Result) {
+  PrimType LongType = getLongPrimType(S);
+  if (LongType == PT_Sint64)
+return Ret(S, OpPC, Result);
+  else if (LongType == PT_Sint32)
+return Ret(S, OpPC, Result);
+  else if (LongType == PT_Sint16)
+return Ret(S, OpPC, Result);
+  llvm_unreachable("Int isn't 16 or 32 bit?");
+}
+
 static void pushSizeT(InterpState &S, uint64_t Val) {
   const TargetInfo &TI = S.getCtx().getTargetInfo();
   unsigned SizeTWidth = TI.getTypeWidth(TI.getSizeType());
@@ -409,6 +446,27 @@ static bool interp__builtin_popcount(InterpState &S, 
CodePtr OpPC,
   return true;
 }
 
+// __builtin_expect(long, long) or
+// __builtin_expect_with_probability(long, long, double)
+static bool interp__builtin_expect(InterpState &S, CodePtr OpPC,
+   const InterpFrame *Frame,
+   const Function *Func, const CallExpr *Call) 
{
+  // The return value is simply the value of the first parameter.
+  // We ignore the probability.
+  unsigned NumArgs = Call->getNumArgs();
+  PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
+
+  assert(NumArgs == 2 || NumArgs == 3);
+
+  unsigned Offset = align(primSize(getLongPrimType(S))) * 2;
+  if (NumArgs == 3)
+Offset += align(primSize(PT_Float));
+
+  APSInt Val = peekToAPSInt(S.Stk, ArgT, Offset);
+  pushLong(S, Val.getSExtValue());
+  return true;
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
@@ -534,6 +592,12 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
Function *F,
   return retInt(S, OpPC, Dummy);
 break;
 
+  case Builtin::BI__builtin_expect:
+  case Builtin::BI__builtin_expect_with_probability:
+if (interp__builtin_expect(S, OpPC, Frame, F, Call))
+  return retLong(S, OpPC, Dummy);
+break;
+
   default:
 return false;
   }
diff --git a/clang/test/AST/Interp/builtin-functions.cpp 
b/clang/test/AST/Interp/builtin-functions.cpp
index 65361d67d68d578..d928b494a5204a6 100644
--- a/clang/test/AST/Interp/builtin-functions.cpp
+++ b/clang/test/AST/Interp/builtin-functions.cpp
@@ -282,3 +282,11 @@ namespace popcount {
   char popcount9[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1];
   char popcount10[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1];
 }
+
+namespace expect {
+  constexpr int a() {
+return 12;
+  }
+  static_assert(__builtin_expect(a(),1) == 12, "");
+  static_assert(__builtin_expect_with_probability(a(), 1, 1.0) == 12, "");
+}
diff --git a/clang/test/Sema/builtin-expect-with-probability.cpp 
b/clang/test/Sema/builtin-expect-with-probability.cpp

[clang] [clang][Interp] Implement builtin_expect (PR #69713)

2023-10-21 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/69713

>From 1d60343ec3acb89764ab56a7035e1d7355e741ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 20 Oct 2023 14:16:22 +0200
Subject: [PATCH 1/2] [clang][Interp] Implement builtin_expect

---
 clang/lib/AST/Interp/InterpBuiltin.cpp| 64 +++
 clang/test/AST/Interp/builtin-functions.cpp   |  8 +++
 .../Sema/builtin-expect-with-probability.cpp  |  1 +
 3 files changed, 73 insertions(+)

diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 7552c1b88cff60c..48678b468e82ed5 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -33,6 +33,19 @@ PrimType getIntPrimType(const InterpState &S) {
   llvm_unreachable("Int isn't 16 or 32 bit?");
 }
 
+PrimType getLongPrimType(const InterpState &S) {
+  const TargetInfo &TI = S.getCtx().getTargetInfo();
+  unsigned LongWidth = TI.getLongWidth();
+
+  if (LongWidth == 64)
+return PT_Sint64;
+  else if (LongWidth == 32)
+return PT_Sint32;
+  else if (LongWidth == 16)
+return PT_Sint16;
+  llvm_unreachable("long isn't 16, 32 or 64 bit?");
+}
+
 /// Peek an integer value from the stack into an APSInt.
 static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset = 0) {
   if (Offset == 0)
@@ -59,6 +72,19 @@ static void pushInt(InterpState &S, int32_t Val) {
 llvm_unreachable("Int isn't 16 or 32 bit?");
 }
 
+/// Pushes \p Val to the stack, as a target-dependent 'long'.
+static void pushLong(InterpState &S, int64_t Val) {
+  PrimType LongType = getLongPrimType(S);
+  if (LongType == PT_Sint64)
+S.Stk.push>(Integral<64, true>::from(Val));
+  else if (LongType == PT_Sint32)
+S.Stk.push>(Integral<32, true>::from(Val));
+  else if (LongType == PT_Sint16)
+S.Stk.push>(Integral<16, true>::from(Val));
+  else
+llvm_unreachable("Long isn't 16, 32 or 64 bit?");
+}
+
 static bool retInt(InterpState &S, CodePtr OpPC, APValue &Result) {
   PrimType IntType = getIntPrimType(S);
   if (IntType == PT_Sint32)
@@ -68,6 +94,17 @@ static bool retInt(InterpState &S, CodePtr OpPC, APValue 
&Result) {
   llvm_unreachable("Int isn't 16 or 32 bit?");
 }
 
+static bool retLong(InterpState &S, CodePtr OpPC, APValue &Result) {
+  PrimType LongType = getLongPrimType(S);
+  if (LongType == PT_Sint64)
+return Ret(S, OpPC, Result);
+  else if (LongType == PT_Sint32)
+return Ret(S, OpPC, Result);
+  else if (LongType == PT_Sint16)
+return Ret(S, OpPC, Result);
+  llvm_unreachable("Int isn't 16 or 32 bit?");
+}
+
 static void pushSizeT(InterpState &S, uint64_t Val) {
   const TargetInfo &TI = S.getCtx().getTargetInfo();
   unsigned SizeTWidth = TI.getTypeWidth(TI.getSizeType());
@@ -409,6 +446,27 @@ static bool interp__builtin_popcount(InterpState &S, 
CodePtr OpPC,
   return true;
 }
 
+// __builtin_expect(long, long) or
+// __builtin_expect_with_probability(long, long, double)
+static bool interp__builtin_expect(InterpState &S, CodePtr OpPC,
+   const InterpFrame *Frame,
+   const Function *Func, const CallExpr *Call) 
{
+  // The return value is simply the value of the first parameter.
+  // We ignore the probability.
+  unsigned NumArgs = Call->getNumArgs();
+  PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
+
+  assert(NumArgs == 2 || NumArgs == 3);
+
+  unsigned Offset = align(primSize(getLongPrimType(S))) * 2;
+  if (NumArgs == 3)
+Offset += align(primSize(PT_Float));
+
+  APSInt Val = peekToAPSInt(S.Stk, ArgT, Offset);
+  pushLong(S, Val.getSExtValue());
+  return true;
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
@@ -534,6 +592,12 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
Function *F,
   return retInt(S, OpPC, Dummy);
 break;
 
+  case Builtin::BI__builtin_expect:
+  case Builtin::BI__builtin_expect_with_probability:
+if (interp__builtin_expect(S, OpPC, Frame, F, Call))
+  return retLong(S, OpPC, Dummy);
+break;
+
   default:
 return false;
   }
diff --git a/clang/test/AST/Interp/builtin-functions.cpp 
b/clang/test/AST/Interp/builtin-functions.cpp
index 65361d67d68d578..d928b494a5204a6 100644
--- a/clang/test/AST/Interp/builtin-functions.cpp
+++ b/clang/test/AST/Interp/builtin-functions.cpp
@@ -282,3 +282,11 @@ namespace popcount {
   char popcount9[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1];
   char popcount10[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1];
 }
+
+namespace expect {
+  constexpr int a() {
+return 12;
+  }
+  static_assert(__builtin_expect(a(),1) == 12, "");
+  static_assert(__builtin_expect_with_probability(a(), 1, 1.0) == 12, "");
+}
diff --git a/clang/test/Sema/builtin-expect-with-probability.cpp

[clang] [clang][Interp] Implement builtin_expect (PR #69713)

2023-11-27 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/69713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement builtin_expect (PR #69713)

2023-11-28 Thread via cfe-commits

https://github.com/cor3ntin approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/69713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement builtin_expect (PR #69713)

2023-11-28 Thread via cfe-commits


@@ -34,6 +34,19 @@ PrimType getIntPrimType(const InterpState &S) {
   llvm_unreachable("Int isn't 16 or 32 bit?");
 }
 
+PrimType getLongPrimType(const InterpState &S) {

cor3ntin wrote:

I don't suppose we can merge with getIntPrimType ?

https://github.com/llvm/llvm-project/pull/69713
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits