https://github.com/chapuni created 
https://github.com/llvm/llvm-project/pull/125405

Fixes #124565

>From f70a6c8686617963c55854c2d8c6fa8607ca0806 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4ci...@gmail.com>
Date: Sun, 2 Feb 2025 22:10:25 +0900
Subject: [PATCH] [MC/DC] Handle __builtin_expect as if parenthses

Fixes #124565
---
 clang/include/clang/AST/IgnoreExpr.h            |  9 +++++++++
 clang/lib/CodeGen/CodeGenFunction.cpp           | 13 ++++++++-----
 clang/lib/CodeGen/CodeGenPGO.cpp                |  8 +++++---
 clang/test/CoverageMapping/mcdc-nested-expr.cpp |  5 ++++-
 4 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/clang/include/clang/AST/IgnoreExpr.h 
b/clang/include/clang/AST/IgnoreExpr.h
index 917bada61fa6fdd..c366aa176674815 100644
--- a/clang/include/clang/AST/IgnoreExpr.h
+++ b/clang/include/clang/AST/IgnoreExpr.h
@@ -134,6 +134,15 @@ inline Expr 
*IgnoreElidableImplicitConstructorSingleStep(Expr *E) {
   return E;
 }
 
+inline Expr *IgnoreBuiltinExpectSingleStep(Expr *E) {
+  if (auto *CE = dyn_cast<CallExpr>(E)) {
+    if (const FunctionDecl *FD = CE->getDirectCallee())
+      if (FD->getBuiltinID() == Builtin::BI__builtin_expect)
+        return CE->getArg(0);
+  }
+  return E;
+}
+
 inline Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) {
   if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
     return ICE->getSubExprAsWritten();
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp 
b/clang/lib/CodeGen/CodeGenFunction.cpp
index bbef277a524480b..05766aa7693d2e1 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -27,6 +27,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/IgnoreExpr.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/Basic/Builtins.h"
@@ -1748,12 +1749,14 @@ bool 
CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,
 
 /// Strip parentheses and simplistic logical-NOT operators.
 const Expr *CodeGenFunction::stripCond(const Expr *C) {
-  while (const UnaryOperator *Op = dyn_cast<UnaryOperator>(C->IgnoreParens())) 
{
-    if (Op->getOpcode() != UO_LNot)
-      break;
-    C = Op->getSubExpr();
+  while (true) {
+    const Expr *SC = IgnoreExprNodes(C, IgnoreParensSingleStep,
+                                     IgnoreBuiltinExpectSingleStep,
+                                     IgnoreImplicitCastsSingleStep);
+    if (C == SC)
+      return SC;
+    C = SC;
   }
-  return C->IgnoreParens();
 }
 
 /// Determine whether the given condition is an instrumentable condition
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 792373839107f0a..0fd49b880bba305 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -247,8 +247,9 @@ struct MapRegionCounters : public 
RecursiveASTVisitor<MapRegionCounters> {
     }
 
     if (const Expr *E = dyn_cast<Expr>(S)) {
-      const BinaryOperator *BinOp = 
dyn_cast<BinaryOperator>(E->IgnoreParens());
-      if (BinOp && BinOp->isLogicalOp()) {
+      if (const auto *BinOp =
+              dyn_cast<BinaryOperator>(CodeGenFunction::stripCond(E));
+          BinOp && BinOp->isLogicalOp()) {
         /// Check for "split-nested" logical operators. This happens when a new
         /// boolean expression logical-op nest is encountered within an 
existing
         /// boolean expression, separated by a non-logical operator.  For
@@ -280,7 +281,8 @@ struct MapRegionCounters : public 
RecursiveASTVisitor<MapRegionCounters> {
       return true;
 
     if (const Expr *E = dyn_cast<Expr>(S)) {
-      const BinaryOperator *BinOp = 
dyn_cast<BinaryOperator>(E->IgnoreParens());
+      const BinaryOperator *BinOp =
+          dyn_cast<BinaryOperator>(CodeGenFunction::stripCond(E));
       if (BinOp && BinOp->isLogicalOp()) {
         assert(LogOpStack.back() == BinOp);
         LogOpStack.pop_back();
diff --git a/clang/test/CoverageMapping/mcdc-nested-expr.cpp 
b/clang/test/CoverageMapping/mcdc-nested-expr.cpp
index bb82873e3b600d0..0614a2b7ab8c101 100644
--- a/clang/test/CoverageMapping/mcdc-nested-expr.cpp
+++ b/clang/test/CoverageMapping/mcdc-nested-expr.cpp
@@ -21,8 +21,11 @@ bool func_condop(bool a, bool b, bool c) {
 // Treated as parentheses.
 // CHECK: func_expect{{.*}}:
 bool func_expect(bool a, bool b, bool c) {
-  // WARN: :[[@LINE+1]]:10: warning: unsupported MC/DC boolean expression; 
contains an operation with a nested boolean expression.
   return a || __builtin_expect(b && c, true);
+  // CHECK:  Decision,File 0, [[@LINE-1]]:10 -> [[#L:@LINE-1]]:45 = M:4, C:3
+  // CHECK:  Branch,File 0, [[#L]]:10 -> [[#L]]:11 = (#0 - #1), #1 [1,0,2]
+  // CHECK:  Branch,File 0, [[#L]]:32 -> [[#L]]:33 = #2, (#1 - #2) [2,3,0]
+  // CHECK:  Branch,File 0, [[#L]]:37 -> [[#L]]:38 = #3, (#2 - #3) [3,0,0]
 }
 
 // LNot among BinOp(s)

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

Reply via email to