[clang] 2699072 - [clang] Accept lambdas in C++03 as an extensions (#73376)

2024-03-21 Thread via cfe-commits

Author: Nikolas Klauser
Date: 2024-03-21T12:57:24+01:00
New Revision: 2699072b4bc8d8d5e84eb66af38face73ceeb4d3

URL: 
https://github.com/llvm/llvm-project/commit/2699072b4bc8d8d5e84eb66af38face73ceeb4d3
DIFF: 
https://github.com/llvm/llvm-project/commit/2699072b4bc8d8d5e84eb66af38face73ceeb4d3.diff

LOG: [clang] Accept lambdas in C++03 as an extensions (#73376)

Implements
https://discourse.llvm.org/t/rfc-allow-c-11-lambdas-in-c-03-as-an-extension/75262

Added: 
clang/test/Parser/cxx03-lambda-extension.cpp

Modified: 
clang/docs/LanguageExtensions.rst
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/include/clang/Basic/Features.def
clang/lib/Parse/ParseExpr.cpp
clang/lib/Parse/ParseExprCXX.cpp
clang/lib/Parse/ParseInit.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/test/Lexer/has_extension_cxx.cpp
clang/test/OpenMP/declare_reduction_messages.cpp
clang/test/OpenMP/openmp_check.cpp
clang/test/Parser/cxx0x-lambda-expressions.cpp
clang/test/Parser/cxx2b-lambdas.cpp
clang/test/Parser/objcxx-lambda-expressions-neg.mm
clang/test/ParserHLSL/group_shared.hlsl
clang/test/SemaCXX/cxx2a-template-lambdas.cpp
clang/test/SemaCXX/lambda-expressions.cpp
clang/test/SemaCXX/lambda-implicit-this-capture.cpp
clang/test/SemaCXX/lambda-invalid-capture.cpp
clang/test/SemaCXX/new-delete.cpp

Removed: 




diff  --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index 13d7261d83d7f1..201a4c27f7dd8b 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1459,40 +1459,45 @@ More information could be found `here 

 Language Extensions Back-ported to Previous Standards
 =
 
-==  
= =
-FeatureFeature Test Macro   
Introduced In Backported To
-==  
= =
-variadic templates __cpp_variadic_templates C++11  
   C++03
-Alias templates__cpp_alias_templatesC++11  
   C++03
-Non-static data member initializers__cpp_nsdmi  C++11  
   C++03
-Range-based ``for`` loop   __cpp_range_based_forC++11  
   C++03
-RValue references  __cpp_rvalue_references  C++11  
   C++03
-Attributes __cpp_attributes C++11  
   C++03
-variable templates __cpp_variable_templates C++14  
   C++03
-Binary literals__cpp_binary_literalsC++14  
   C++03
-Relaxed constexpr  __cpp_constexpr  C++14  
   C++11
-``if constexpr``   __cpp_if_constexpr   C++17  
   C++11
-fold expressions   __cpp_fold_expressions   C++17  
   C++03
-Lambda capture of \*this by value  __cpp_capture_star_this  C++17  
   C++11
-Attributes on enums__cpp_enumerator_attributes  C++17  
   C++03
-Guaranteed copy elision__cpp_guaranteed_copy_elisionC++17  
   C++03
-Hexadecimal floating literals  __cpp_hex_float  C++17  
   C++03
-``inline`` variables   __cpp_inline_variables   C++17  
   C++03
-Attributes on namespaces   __cpp_namespace_attributes   C++17  
   C++11
-Structured bindings__cpp_structured_bindingsC++17  
   C++03
-template template arguments__cpp_template_template_args C++17  
   C++03
-``static operator[]``  __cpp_multidimensional_subscript C++20  
   C++03
-Designated initializers__cpp_designated_initializersC++20  
   C++03
-Conditional ``explicit``   __cpp_conditional_explicit   C++20  
   C++03
-``using enum`` __cpp_using_enum C++20  
   C++03
-``if consteval``   __cpp_if_consteval   C++23  
   C++20
-``static operator()``  __cpp_static_call_operator   C++23  
   C++03
-Attributes on Lambda-ExpressionsC++23  
   C++11
---  
- -
-Designated initializers (N494)  C99
   C89
-Array & element qualification (N2607)   C23
   C89

[clang] [llvm] [AsmPrinter,X86] Hard code AT syntax input for module-level inline assembly for MSVC triples (PR #85668)

2024-03-21 Thread Nico Weber via cfe-commits

nico wrote:

Looks like we could fix code on our end and this here isn't needed. But maybe 
the current behavior isn't 100% ideal.

Here's what I think the situation currently is (please correct me if I'm wrong):
* With clang-cl, you get intel assembly output by default with `/FA`. That's 
good.
* With clang, you get AT assembly output by default with `-S`, and intel 
assembly output with -masm=intel. That's good.
* With clang, the syntax for `asm()` is AT by default, and intel with 
-masm=intel. That's good.
* With clang-cl, `__asm { ... }` blocks always use Intel syntax. That's good.
* With clang-cl, the syntax for `asm()` is intel by default, and there's no way 
to change this. (This is now consistent between module-level assembly and 
function-local assembly. It's good that they're consistent, that's better than 
before.)

The last point seems suboptimal to me. cl.exe doesn't support `asm()`, only 
`__asm {}`. So users that use `asm()` with clang-cl probably want to share that 
code with other platforms where they use `asm()` too.

Ideally, clang-cl could use intel asm output by default, intel asm input for 
`__asm {}` blocks, but at style asm input for `asm()`. And ideally it could 
also offer a flag to opt in to intel style asm input for `asm()`. (And the 
pragma mentioned in https://reviews.llvm.org/D113707 might be nice too.)

Does that sound right?

(I'm not saying you have to do any of this! Just want to check if we agree on 
this assessment of the state of the world.)

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


[clang] [clang] Improves -print-library-module-manifest-path. (PR #85943)

2024-03-21 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-driver

Author: Mark de Wever (mordante)


Changes

This adds a libc++ to modules.json as is currently used by libc++. When 
libc++.so is not found the function will search for libc++.a as fallback.

---
Full diff: https://github.com/llvm/llvm-project/pull/85943.diff


2 Files Affected:

- (modified) clang/lib/Driver/Driver.cpp (+28-21) 
- (modified) clang/test/Driver/modules-print-library-module-manifest-path.cpp 
(+17-2) 


``diff
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 1daf588142b3b4..94dd1aa27e256b 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -6199,28 +6199,35 @@ std::string Driver::GetStdModuleManifestPath(const 
Compilation ,
 
   switch (TC.GetCXXStdlibType(C.getArgs())) {
   case ToolChain::CST_Libcxx: {
-std::string lib = GetFilePath("libc++.so", TC);
-
-// Note when there are multiple flavours of libc++ the module json needs to
-// look at the command-line arguments for the proper json.
-// These flavours do not exist at the moment, but there are plans to
-// provide a variant that is built with sanitizer instrumentation enabled.
-
-// For example
-//  StringRef modules = [&] {
-//const SanitizerArgs  = TC.getSanitizerArgs(C.getArgs());
-//if (Sanitize.needsAsanRt())
-//  return "modules-asan.json";
-//return "modules.json";
-//  }();
-
-SmallString<128> path(lib.begin(), lib.end());
-llvm::sys::path::remove_filename(path);
-llvm::sys::path::append(path, "modules.json");
-if (TC.getVFS().exists(path))
-  return static_cast(path);
+auto evaluate = [&](const char *library) -> std::optional {
+  std::string lib = GetFilePath(library, TC);
+
+  // Note when there are multiple flavours of libc++ the module json needs
+  // to look at the command-line arguments for the proper json. These
+  // flavours do not exist at the moment, but there are plans to provide a
+  // variant that is built with sanitizer instrumentation enabled.
+
+  // For example
+  //  StringRef modules = [&] {
+  //const SanitizerArgs  = TC.getSanitizerArgs(C.getArgs());
+  //if (Sanitize.needsAsanRt())
+  //  return "libc++.modules-asan.json";
+  //return "libc++.modules.json";
+  //  }();
+
+  SmallString<128> path(lib.begin(), lib.end());
+  llvm::sys::path::remove_filename(path);
+  llvm::sys::path::append(path, "libc++.modules.json");
+  if (TC.getVFS().exists(path))
+return static_cast(path);
+
+  return {};
+};
 
-return error;
+if (std::optional result = evaluate("libc++.so"); result)
+  return *result;
+
+return evaluate("libc++.a").value_or(error);
   }
 
   case ToolChain::CST_Libstdcxx:
diff --git a/clang/test/Driver/modules-print-library-module-manifest-path.cpp 
b/clang/test/Driver/modules-print-library-module-manifest-path.cpp
index 24797002b80f53..3ba2709ad95cc8 100644
--- a/clang/test/Driver/modules-print-library-module-manifest-path.cpp
+++ b/clang/test/Driver/modules-print-library-module-manifest-path.cpp
@@ -3,6 +3,7 @@
 // RUN: rm -rf %t && split-file %s %t && cd %t
 // RUN: mkdir -p %t/Inputs/usr/lib/x86_64-linux-gnu
 // RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.so
+// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.a
 
 // RUN: %clang -print-library-module-manifest-path \
 // RUN: -stdlib=libc++ \
@@ -10,13 +11,21 @@
 // RUN: --target=x86_64-linux-gnu 2>&1 \
 // RUN:   | FileCheck libcxx-no-module-json.cpp
 
-// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/modules.json
+// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.modules.json
 // RUN: %clang -print-library-module-manifest-path \
 // RUN: -stdlib=libc++ \
 // RUN: -resource-dir=%t/Inputs/usr/lib/x86_64-linux-gnu \
 // RUN: --target=x86_64-linux-gnu 2>&1 \
 // RUN:   | FileCheck libcxx.cpp
 
+// RUN: rm %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.so
+// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.a
+// RUN: %clang -print-library-module-manifest-path \
+// RUN: -stdlib=libc++ \
+// RUN: -resource-dir=%t/Inputs/usr/lib/x86_64-linux-gnu \
+// RUN: --target=x86_64-linux-gnu 2>&1 \
+// RUN:   | FileCheck libcxx-no-shared-lib.cpp
+
 // RUN: %clang -print-library-module-manifest-path \
 // RUN: -stdlib=libstdc++ \
 // RUN: -resource-dir=%t/Inputs/usr/lib/x86_64-linux-gnu \
@@ -29,7 +38,13 @@
 
 //--- libcxx.cpp
 
-// CHECK: {{.*}}/Inputs/usr/lib/x86_64-linux-gnu{{/|\\}}modules.json
+// CHECK: {{.*}}/Inputs/usr/lib/x86_64-linux-gnu{{/|\\}}libc++.modules.json
+
+//--- libcxx-no-shared-lib.cpp
+
+// Note this might find a different path depending whether search path
+// contains a different libc++.so.
+// CHECK: {{.*}}libc++.modules.json
 
 //--- libstdcxx.cpp
 

``




https://github.com/llvm/llvm-project/pull/85943
___

[clang] [clang] Improves -print-library-module-manifest-path. (PR #85943)

2024-03-21 Thread Mark de Wever via cfe-commits

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


[clang] [clang] Improves -print-library-module-manifest-path. (PR #85943)

2024-03-21 Thread Mark de Wever via cfe-commits


@@ -3,20 +3,29 @@
 // RUN: rm -rf %t && split-file %s %t && cd %t
 // RUN: mkdir -p %t/Inputs/usr/lib/x86_64-linux-gnu
 // RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.so
+// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.a
 
 // RUN: %clang -print-library-module-manifest-path \
 // RUN: -stdlib=libc++ \
 // RUN: -resource-dir=%t/Inputs/usr/lib/x86_64-linux-gnu \
 // RUN: --target=x86_64-linux-gnu 2>&1 \
 // RUN:   | FileCheck libcxx-no-module-json.cpp
 
-// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/modules.json
+// RUN: touch %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.modules.json
 // RUN: %clang -print-library-module-manifest-path \
 // RUN: -stdlib=libc++ \
 // RUN: -resource-dir=%t/Inputs/usr/lib/x86_64-linux-gnu \
 // RUN: --target=x86_64-linux-gnu 2>&1 \
 // RUN:   | FileCheck libcxx.cpp
 
+// RUN: rm %t/Inputs/usr/lib/x86_64-linux-gnu/libc++.so

mordante wrote:

Note this test is a bit tricky since it may find other `libc++.so` files in 
Clang's search path. I didn't find a way to remove the "default" search path.

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


[clang] [RISCV][FMV] Support target_clones (PR #85786)

2024-03-21 Thread Luke Lau via cfe-commits

lukel97 wrote:

Can this land until #85790 lands?

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


[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [X86][Headers] Specify result of NaN comparisons (PR #85862)

2024-03-21 Thread Simon Pilgrim via cfe-commits


@@ -207,6 +207,8 @@ _mm256_div_ps(__m256 __a, __m256 __b)
 /// Compares two 256-bit vectors of [4 x double] and returns the greater
 ///of each pair of values.
 ///
+///If either value in a comparison is NaN, returns the value from \a __b.

RKSimon wrote:

I don't think so either - we don't need to start explaining general fp 
comparison behaviour, just any x86/sse quirks.

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


[clang] [llvm] [CodeGen][LLVM] Make the `va_list` related intrinsics generic. (PR #85460)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -700,10 +700,13 @@ class MSBuiltin {
 //===--- Variable Argument Handling Intrinsics 
===//
 //
 
-def int_vastart : DefaultAttrsIntrinsic<[], [llvm_ptr_ty], [], 
"llvm.va_start">;
-def int_vacopy  : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], [],
-"llvm.va_copy">;
-def int_vaend   : DefaultAttrsIntrinsic<[], [llvm_ptr_ty], [], "llvm.va_end">;
+def int_vastart : DefaultAttrsIntrinsic<[],
+[llvm_anyptr_ty], [], "llvm.va_start">;
+def int_vacopy  : DefaultAttrsIntrinsic<[],
+[llvm_anyptr_ty, llvm_anyptr_ty], [],
+"llvm.va_copy">;

arsenm wrote:

Would it make sense to emit these as p5.p0 pairs, such that we're assuming it's 
writing to the stack from an arbitrary pointer an optimize down to 
stack-to-stack copies? 

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


[clang] [llvm] [clang][HLSL][SPRI-V] Add convergence intrinsics (PR #80680)

2024-03-21 Thread Matt Arsenault via cfe-commits
Nathan =?utf-8?q?Gauër?= ,
Nathan =?utf-8?q?Gauër?= ,
Nathan =?utf-8?q?Gauër?= ,
Nathan =?utf-8?q?Gauër?= ,
Nathan =?utf-8?q?Gauër?= ,
Nathan =?utf-8?q?Gauër?= 
Message-ID:
In-Reply-To: 



@@ -1295,11 +1295,13 @@ double4 trunc(double4);
 /// true, across all active lanes in the current wave.
 _HLSL_AVAILABILITY(shadermodel, 6.0)
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_count_bits)
+__attribute__((convergent))

arsenm wrote:

For today you just have to put convergent on every function, you're just stuck 
with the crappy IR design decisions we have now. The noconvergent patch cleans 
this up to be a less bug prone state consistent with all the other optimization 
attributes, this doesn't need to wait for that. You just have to follow along 
with OpenCL/HIP/CUDA/OpenMP and say yes for 
LangOpts.assumeFunctionsAreConvergent

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


[clang] [llvm] [clang][HLSL][SPRI-V] Add convergence intrinsics (PR #80680)

2024-03-21 Thread Matt Arsenault via cfe-commits
Nathan =?utf-8?q?Gauër?= ,
Nathan =?utf-8?q?Gauër?= ,
Nathan =?utf-8?q?Gauër?= ,
Nathan =?utf-8?q?Gauër?= ,
Nathan =?utf-8?q?Gauër?= ,
Nathan =?utf-8?q?Gauër?= 
Message-ID:
In-Reply-To: 



@@ -1295,11 +1295,13 @@ double4 trunc(double4);
 /// true, across all active lanes in the current wave.
 _HLSL_AVAILABILITY(shadermodel, 6.0)
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_count_bits)
+__attribute__((convergent))

arsenm wrote:

Convergence requires all transitive callers to also be convergent. No real code 
is going to do this. The existence of convergence operations means you have a 
convergent language and must optimize to known-not-convergent 

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


[clang] b433076 - [clang][CodeGen] Allow `memcpy` replace with trivial auto var init

2024-03-21 Thread Antonio Frighetto via cfe-commits

Author: Antonio Frighetto
Date: 2024-03-21T09:55:04+01:00
New Revision: b433076fcbacba8a3b91446390bbea5843322bcd

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

LOG: [clang][CodeGen] Allow `memcpy` replace with trivial auto var init

When emitting the storage (or memory copy operations) for constant
initializers, the decision whether to split a constant structure or
array store into a sequence of field stores or to use `memcpy` is
based upon the optimization level and the size of the initializer.
In afe8b93ffdfef5d8879e1894b9d7dda40dee2b8d, we extended this by
allowing constants to be split when the array (or struct) type does
not match the type of data the address to the object (constant) is
expected to contain. This may happen when `emitStoresForConstant` is
called by `EmitAutoVarInit`, as the element type of the address gets
shrunk. When this occurs, let the initializer be split into a bunch
of stores only under `-ftrivial-auto-var-init=pattern`.

Fixes: https://github.com/llvm/llvm-project/issues/84178.

Added: 


Modified: 
clang/lib/CodeGen/CGDecl.cpp
clang/test/CodeGen/aapcs-align.cpp
clang/test/CodeGen/aapcs64-align.cpp
clang/test/CodeGen/attr-counted-by.c
clang/test/CodeGenCXX/auto-var-init.cpp
clang/test/CodeGenOpenCL/amdgpu-printf.cl
clang/test/OpenMP/bug54082.c

Removed: 




diff  --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index dc42faf8dbb9fd..2ef5ed04af30b6 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1242,27 +1242,38 @@ static void emitStoresForConstant(CodeGenModule , 
const VarDecl ,
 return;
   }
 
-  // If the initializer is small, use a handful of stores.
+  // If the initializer is small or trivialAutoVarInit is set, use a handful of
+  // stores.
+  bool IsTrivialAutoVarInitPattern =
+  CGM.getContext().getLangOpts().getTrivialAutoVarInit() ==
+  LangOptions::TrivialAutoVarInitKind::Pattern;
   if (shouldSplitConstantStore(CGM, ConstantSize)) {
 if (auto *STy = dyn_cast(Ty)) {
-  const llvm::StructLayout *Layout =
-  CGM.getDataLayout().getStructLayout(STy);
-  for (unsigned i = 0; i != constant->getNumOperands(); i++) {
-CharUnits CurOff = 
CharUnits::fromQuantity(Layout->getElementOffset(i));
-Address EltPtr = Builder.CreateConstInBoundsByteGEP(
-Loc.withElementType(CGM.Int8Ty), CurOff);
-emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
-  constant->getAggregateElement(i), IsAutoInit);
+  if (STy == Loc.getElementType() ||
+  (STy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) {
+const llvm::StructLayout *Layout =
+CGM.getDataLayout().getStructLayout(STy);
+for (unsigned i = 0; i != constant->getNumOperands(); i++) {
+  CharUnits CurOff =
+  CharUnits::fromQuantity(Layout->getElementOffset(i));
+  Address EltPtr = Builder.CreateConstInBoundsByteGEP(
+  Loc.withElementType(CGM.Int8Ty), CurOff);
+  emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
+constant->getAggregateElement(i), IsAutoInit);
+}
+return;
   }
-  return;
 } else if (auto *ATy = dyn_cast(Ty)) {
-  for (unsigned i = 0; i != ATy->getNumElements(); i++) {
-Address EltPtr = Builder.CreateConstGEP(
-Loc.withElementType(ATy->getElementType()), i);
-emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
-  constant->getAggregateElement(i), IsAutoInit);
+  if (ATy == Loc.getElementType() ||
+  (ATy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) {
+for (unsigned i = 0; i != ATy->getNumElements(); i++) {
+  Address EltPtr = Builder.CreateConstGEP(
+  Loc.withElementType(ATy->getElementType()), i);
+  emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
+constant->getAggregateElement(i), IsAutoInit);
+}
+return;
   }
-  return;
 }
   }
 

diff  --git a/clang/test/CodeGen/aapcs-align.cpp 
b/clang/test/CodeGen/aapcs-align.cpp
index 2886a32974b066..4f393d9e6b7f32 100644
--- a/clang/test/CodeGen/aapcs-align.cpp
+++ b/clang/test/CodeGen/aapcs-align.cpp
@@ -134,8 +134,8 @@ void g6() {
   f6m(1, 2, 3, 4, 5, s);
 }
 // CHECK: define{{.*}} void @g6
-// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0])
-// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 
noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0])
+// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 
undef])
+// CHECK: call void 

[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)

2024-03-21 Thread Antonio Frighetto via cfe-commits

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


[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)

2024-03-21 Thread Antonio Frighetto via cfe-commits

https://github.com/antoniofrighetto updated 
https://github.com/llvm/llvm-project/pull/84230

>From b433076fcbacba8a3b91446390bbea5843322bcd Mon Sep 17 00:00:00 2001
From: Antonio Frighetto 
Date: Thu, 7 Mar 2024 07:49:40 +0100
Subject: [PATCH] [clang][CodeGen] Allow `memcpy` replace with trivial auto var
 init

When emitting the storage (or memory copy operations) for constant
initializers, the decision whether to split a constant structure or
array store into a sequence of field stores or to use `memcpy` is
based upon the optimization level and the size of the initializer.
In afe8b93ffdfef5d8879e1894b9d7dda40dee2b8d, we extended this by
allowing constants to be split when the array (or struct) type does
not match the type of data the address to the object (constant) is
expected to contain. This may happen when `emitStoresForConstant` is
called by `EmitAutoVarInit`, as the element type of the address gets
shrunk. When this occurs, let the initializer be split into a bunch
of stores only under `-ftrivial-auto-var-init=pattern`.

Fixes: https://github.com/llvm/llvm-project/issues/84178.
---
 clang/lib/CodeGen/CGDecl.cpp  | 43 ++-
 clang/test/CodeGen/aapcs-align.cpp|  4 +--
 clang/test/CodeGen/aapcs64-align.cpp  |  8 ++---
 clang/test/CodeGen/attr-counted-by.c  | 26 --
 clang/test/CodeGenCXX/auto-var-init.cpp   | 27 +++---
 clang/test/CodeGenOpenCL/amdgpu-printf.cl |  9 +
 clang/test/OpenMP/bug54082.c  |  4 +--
 7 files changed, 56 insertions(+), 65 deletions(-)

diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index dc42faf8dbb9fd..2ef5ed04af30b6 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1242,27 +1242,38 @@ static void emitStoresForConstant(CodeGenModule , 
const VarDecl ,
 return;
   }
 
-  // If the initializer is small, use a handful of stores.
+  // If the initializer is small or trivialAutoVarInit is set, use a handful of
+  // stores.
+  bool IsTrivialAutoVarInitPattern =
+  CGM.getContext().getLangOpts().getTrivialAutoVarInit() ==
+  LangOptions::TrivialAutoVarInitKind::Pattern;
   if (shouldSplitConstantStore(CGM, ConstantSize)) {
 if (auto *STy = dyn_cast(Ty)) {
-  const llvm::StructLayout *Layout =
-  CGM.getDataLayout().getStructLayout(STy);
-  for (unsigned i = 0; i != constant->getNumOperands(); i++) {
-CharUnits CurOff = 
CharUnits::fromQuantity(Layout->getElementOffset(i));
-Address EltPtr = Builder.CreateConstInBoundsByteGEP(
-Loc.withElementType(CGM.Int8Ty), CurOff);
-emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
-  constant->getAggregateElement(i), IsAutoInit);
+  if (STy == Loc.getElementType() ||
+  (STy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) {
+const llvm::StructLayout *Layout =
+CGM.getDataLayout().getStructLayout(STy);
+for (unsigned i = 0; i != constant->getNumOperands(); i++) {
+  CharUnits CurOff =
+  CharUnits::fromQuantity(Layout->getElementOffset(i));
+  Address EltPtr = Builder.CreateConstInBoundsByteGEP(
+  Loc.withElementType(CGM.Int8Ty), CurOff);
+  emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
+constant->getAggregateElement(i), IsAutoInit);
+}
+return;
   }
-  return;
 } else if (auto *ATy = dyn_cast(Ty)) {
-  for (unsigned i = 0; i != ATy->getNumElements(); i++) {
-Address EltPtr = Builder.CreateConstGEP(
-Loc.withElementType(ATy->getElementType()), i);
-emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
-  constant->getAggregateElement(i), IsAutoInit);
+  if (ATy == Loc.getElementType() ||
+  (ATy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) {
+for (unsigned i = 0; i != ATy->getNumElements(); i++) {
+  Address EltPtr = Builder.CreateConstGEP(
+  Loc.withElementType(ATy->getElementType()), i);
+  emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
+constant->getAggregateElement(i), IsAutoInit);
+}
+return;
   }
-  return;
 }
   }
 
diff --git a/clang/test/CodeGen/aapcs-align.cpp 
b/clang/test/CodeGen/aapcs-align.cpp
index 2886a32974b066..4f393d9e6b7f32 100644
--- a/clang/test/CodeGen/aapcs-align.cpp
+++ b/clang/test/CodeGen/aapcs-align.cpp
@@ -134,8 +134,8 @@ void g6() {
   f6m(1, 2, 3, 4, 5, s);
 }
 // CHECK: define{{.*}} void @g6
-// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0])
-// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 
noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0])
+// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 
undef])
+// CHECK: call void 

[clang] [clang][CodeGen] Allow memcpy replace with trivial auto var init (PR #84230)

2024-03-21 Thread Antonio Frighetto via cfe-commits

https://github.com/antoniofrighetto updated 
https://github.com/llvm/llvm-project/pull/84230

>From bfc29a350458e9b8d20d7398595c3f36503e2d72 Mon Sep 17 00:00:00 2001
From: Antonio Frighetto 
Date: Thu, 7 Mar 2024 07:49:40 +0100
Subject: [PATCH] [clang][CodeGen] Allow `memcpy` replace with trivial auto var
 init

When emitting the storage (or memory copy operations) for constant
initializers, the decision whether to split a constant structure or
array store into a sequence of field stores or to use `memcpy` is
based upon the optimization level and the size of the initializer.
In afe8b93ffdfef5d8879e1894b9d7dda40dee2b8d, we extended this by
allowing constants to be split when the array (or struct) type does
not match the type of data the address to the object (constant) is
expected to contain. This may happen when `emitStoresForConstant` is
called by `EmitAutoVarInit`, as the element type of the address gets
shrunk. When this occurs, let the initializer be split into a bunch
of stores only under `-ftrivial-auto-var-init=pattern`.

Fixes: https://github.com/llvm/llvm-project/issues/84178.
---
 clang/lib/CodeGen/CGDecl.cpp  | 43 ++-
 clang/test/CodeGen/aapcs-align.cpp|  4 +--
 clang/test/CodeGen/aapcs64-align.cpp  |  8 ++---
 clang/test/CodeGen/attr-counted-by.c  | 26 --
 clang/test/CodeGenCXX/auto-var-init.cpp   | 27 +++---
 clang/test/CodeGenOpenCL/amdgpu-printf.cl |  9 +
 clang/test/OpenMP/bug54082.c  |  4 +--
 7 files changed, 56 insertions(+), 65 deletions(-)

diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index dc42faf8dbb9fd..2ef5ed04af30b6 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1242,27 +1242,38 @@ static void emitStoresForConstant(CodeGenModule , 
const VarDecl ,
 return;
   }
 
-  // If the initializer is small, use a handful of stores.
+  // If the initializer is small or trivialAutoVarInit is set, use a handful of
+  // stores.
+  bool IsTrivialAutoVarInitPattern =
+  CGM.getContext().getLangOpts().getTrivialAutoVarInit() ==
+  LangOptions::TrivialAutoVarInitKind::Pattern;
   if (shouldSplitConstantStore(CGM, ConstantSize)) {
 if (auto *STy = dyn_cast(Ty)) {
-  const llvm::StructLayout *Layout =
-  CGM.getDataLayout().getStructLayout(STy);
-  for (unsigned i = 0; i != constant->getNumOperands(); i++) {
-CharUnits CurOff = 
CharUnits::fromQuantity(Layout->getElementOffset(i));
-Address EltPtr = Builder.CreateConstInBoundsByteGEP(
-Loc.withElementType(CGM.Int8Ty), CurOff);
-emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
-  constant->getAggregateElement(i), IsAutoInit);
+  if (STy == Loc.getElementType() ||
+  (STy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) {
+const llvm::StructLayout *Layout =
+CGM.getDataLayout().getStructLayout(STy);
+for (unsigned i = 0; i != constant->getNumOperands(); i++) {
+  CharUnits CurOff =
+  CharUnits::fromQuantity(Layout->getElementOffset(i));
+  Address EltPtr = Builder.CreateConstInBoundsByteGEP(
+  Loc.withElementType(CGM.Int8Ty), CurOff);
+  emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
+constant->getAggregateElement(i), IsAutoInit);
+}
+return;
   }
-  return;
 } else if (auto *ATy = dyn_cast(Ty)) {
-  for (unsigned i = 0; i != ATy->getNumElements(); i++) {
-Address EltPtr = Builder.CreateConstGEP(
-Loc.withElementType(ATy->getElementType()), i);
-emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
-  constant->getAggregateElement(i), IsAutoInit);
+  if (ATy == Loc.getElementType() ||
+  (ATy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) {
+for (unsigned i = 0; i != ATy->getNumElements(); i++) {
+  Address EltPtr = Builder.CreateConstGEP(
+  Loc.withElementType(ATy->getElementType()), i);
+  emitStoresForConstant(CGM, D, EltPtr, isVolatile, Builder,
+constant->getAggregateElement(i), IsAutoInit);
+}
+return;
   }
-  return;
 }
   }
 
diff --git a/clang/test/CodeGen/aapcs-align.cpp 
b/clang/test/CodeGen/aapcs-align.cpp
index 2886a32974b066..4f393d9e6b7f32 100644
--- a/clang/test/CodeGen/aapcs-align.cpp
+++ b/clang/test/CodeGen/aapcs-align.cpp
@@ -134,8 +134,8 @@ void g6() {
   f6m(1, 2, 3, 4, 5, s);
 }
 // CHECK: define{{.*}} void @g6
-// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 0])
-// CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 
noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 0])
+// CHECK: call void @f6(i32 noundef 1, [4 x i32] [i32 6, i32 7, i32 0, i32 
undef])
+// CHECK: call void 

[clang] [clang][analyzer] Model more getline/getdelim pre and postconditions (PR #83027)

2024-03-21 Thread Alejandro Álvarez Ayllón via cfe-commits


@@ -1217,6 +1231,11 @@ void StreamChecker::evalGetdelim(const FnDescription 
*Desc,
   E.isStreamEof() ? ErrorFEof : ErrorFEof | ErrorFError;
   StateFailed = E.setStreamState(
   StateFailed, StreamState::getOpened(Desc, NewES, !NewES.isFEof()));
+  // On failure, the content of the buffer is undefined.
+  if (auto NewLinePtr = getPointeeVal(Call.getArgSVal(0), State)) {
+StateFailed = StateFailed->bindLoc(*NewLinePtr, UndefinedVal(),
+   C.getLocationContext());
+  }

alejandro-alvarez-sonarsource wrote:

Removed.

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


[clang] [clang][analyzer] Model more getline/getdelim pre and postconditions (PR #83027)

2024-03-21 Thread Alejandro Álvarez Ayllón via cfe-commits


@@ -1204,6 +1204,20 @@ void StreamChecker::evalGetdelim(const FnDescription 
*Desc,
 State->BindExpr(E.CE, C.getLocationContext(), RetVal);
 StateNotFailed =
 E.assumeBinOpNN(StateNotFailed, BO_GE, RetVal, E.getZeroVal(Call));
+// The buffer size `*n` must be enough to hold the whole line, and
+// greater than the return value, since it has to account for '\0'.
+auto SizePtrSval = Call.getArgSVal(1);
+auto NVal = getPointeeVal(SizePtrSval, State);
+if (NVal) {
+  StateNotFailed = StateNotFailed->assume(
+  E.SVB
+  .evalBinOp(StateNotFailed, BO_GT, *NVal, RetVal,
+ E.SVB.getConditionType())
+  .castAs(),
+  true);
+  StateNotFailed =
+  StateNotFailed->BindExpr(E.CE, C.getLocationContext(), RetVal);

alejandro-alvarez-sonarsource wrote:

Replaced, thanks!

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


[clang] [clang][analyzer] Model more getline/getdelim pre and postconditions (PR #83027)

2024-03-21 Thread Alejandro Álvarez Ayllón via cfe-commits

https://github.com/alejandro-alvarez-sonarsource commented:

Applied the feedback.
By the way, when `StdLibraryFunctionsChecker` is refactored, I'd be happy to 
give a hand if you need updating these checkers (UnixAPI and Stream).

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


[clang] [clang][analyzer] Model more getline/getdelim pre and postconditions (PR #83027)

2024-03-21 Thread Alejandro Álvarez Ayllón via cfe-commits

https://github.com/alejandro-alvarez-sonarsource updated 
https://github.com/llvm/llvm-project/pull/83027

From a061464b75ac02c21e5d74fc4dff8d8afdbba66b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alejandro=20=C3=81lvarez=20Ayll=C3=B3n?=
 
Date: Wed, 20 Mar 2024 10:49:08 +0100
Subject: [PATCH 01/20] [NFC] UnixAPIMisuseChecker inherits from
 Checker

---
 .../Checkers/UnixAPIChecker.cpp   | 60 +--
 1 file changed, 30 insertions(+), 30 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index 19f1ca2dc824c9..599e5e6cedc606 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
@@ -17,6 +17,7 @@
 #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
 #include "llvm/ADT/STLExtras.h"
@@ -41,8 +42,7 @@ enum class OpenVariant {
 namespace {
 
 class UnixAPIMisuseChecker
-: public Checker,
- check::ASTDecl> {
+: public Checker> {
   const BugType BT_open{this, "Improper use of 'open'", categories::UnixAPI};
   const BugType BT_pthreadOnce{this, "Improper use of 'pthread_once'",
categories::UnixAPI};
@@ -52,14 +52,14 @@ class UnixAPIMisuseChecker
   void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager ,
 BugReporter ) const;
 
-  void checkPreStmt(const CallExpr *CE, CheckerContext ) const;
+  void checkPreCall(const CallEvent , CheckerContext ) const;
 
-  void CheckOpen(CheckerContext , const CallExpr *CE) const;
-  void CheckOpenAt(CheckerContext , const CallExpr *CE) const;
-  void CheckPthreadOnce(CheckerContext , const CallExpr *CE) const;
+  void CheckOpen(CheckerContext , const CallEvent ) const;
+  void CheckOpenAt(CheckerContext , const CallEvent ) const;
+  void CheckPthreadOnce(CheckerContext , const CallEvent ) const;
 
-  void CheckOpenVariant(CheckerContext ,
-const CallExpr *CE, OpenVariant Variant) const;
+  void CheckOpenVariant(CheckerContext , const CallEvent ,
+OpenVariant Variant) const;
 
   void ReportOpenBug(CheckerContext , ProgramStateRef State, const char *Msg,
  SourceRange SR) const;
@@ -113,9 +113,9 @@ void UnixAPIMisuseChecker::checkASTDecl(const 
TranslationUnitDecl *TU,
 // "open" (man 2 open)
 //===--===/
 
-void UnixAPIMisuseChecker::checkPreStmt(const CallExpr *CE,
+void UnixAPIMisuseChecker::checkPreCall(const CallEvent ,
 CheckerContext ) const {
-  const FunctionDecl *FD = C.getCalleeDecl(CE);
+  const FunctionDecl *FD = dyn_cast_if_present(Call.getDecl());
   if (!FD || FD->getKind() != Decl::Function)
 return;
 
@@ -130,13 +130,13 @@ void UnixAPIMisuseChecker::checkPreStmt(const CallExpr 
*CE,
 return;
 
   if (FName == "open")
-CheckOpen(C, CE);
+CheckOpen(C, Call);
 
   else if (FName == "openat")
-CheckOpenAt(C, CE);
+CheckOpenAt(C, Call);
 
   else if (FName == "pthread_once")
-CheckPthreadOnce(C, CE);
+CheckPthreadOnce(C, Call);
 }
 void UnixAPIMisuseChecker::ReportOpenBug(CheckerContext ,
  ProgramStateRef State,
@@ -152,17 +152,17 @@ void UnixAPIMisuseChecker::ReportOpenBug(CheckerContext 
,
 }
 
 void UnixAPIMisuseChecker::CheckOpen(CheckerContext ,
- const CallExpr *CE) const {
-  CheckOpenVariant(C, CE, OpenVariant::Open);
+ const CallEvent ) const {
+  CheckOpenVariant(C, Call, OpenVariant::Open);
 }
 
 void UnixAPIMisuseChecker::CheckOpenAt(CheckerContext ,
-   const CallExpr *CE) const {
-  CheckOpenVariant(C, CE, OpenVariant::OpenAt);
+   const CallEvent ) const {
+  CheckOpenVariant(C, Call, OpenVariant::OpenAt);
 }
 
 void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext ,
-const CallExpr *CE,
+const CallEvent ,
 OpenVariant Variant) const {
   // The index of the argument taking the flags open flags (O_RDONLY,
   // O_WRONLY, O_CREAT, etc.),
@@ -191,11 +191,11 @@ void 
UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext ,
 
   ProgramStateRef state = C.getState();
 
-  if (CE->getNumArgs() < MinArgCount) {
+  if (Call.getNumArgs() < MinArgCount) {
 // The frontend should issue a warning for this case. Just return.
 return;
-  } else if 

[clang] [clang][analyzer] Model more getline/getdelim pre and postconditions (PR #83027)

2024-03-21 Thread Alejandro Álvarez Ayllón via cfe-commits


@@ -1204,6 +1204,20 @@ void StreamChecker::evalGetdelim(const FnDescription 
*Desc,
 State->BindExpr(E.CE, C.getLocationContext(), RetVal);
 StateNotFailed =
 E.assumeBinOpNN(StateNotFailed, BO_GE, RetVal, E.getZeroVal(Call));
+// The buffer size `*n` must be enough to hold the whole line, and
+// greater than the return value, since it has to account for '\0'.
+auto SizePtrSval = Call.getArgSVal(1);
+auto NVal = getPointeeVal(SizePtrSval, State);
+if (NVal) {
+  StateNotFailed = StateNotFailed->assume(
+  E.SVB
+  .evalBinOp(StateNotFailed, BO_GT, *NVal, RetVal,
+ E.SVB.getConditionType())
+  .castAs(),
+  true);
+  StateNotFailed =
+  StateNotFailed->BindExpr(E.CE, C.getLocationContext(), RetVal);
+}

alejandro-alvarez-sonarsource wrote:

In `stream.c`, the test `getline_buffer_size_invariant`

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


[clang] [clang][analyzer] Model more getline/getdelim pre and postconditions (PR #83027)

2024-03-21 Thread Alejandro Álvarez Ayllón via cfe-commits


@@ -1179,6 +1195,113 @@ void StreamChecker::evalUngetc(const FnDescription 
*Desc, const CallEvent ,
   C.addTransition(StateFailed);
 }
 
+ProgramStateRef StreamChecker::ensureGetdelimBufferAndSizeCorrect(
+SVal LinePtrPtrSVal, SVal SizePtrSVal, const Expr *LinePtrPtrExpr,
+const Expr *SizePtrExpr, CheckerContext , ProgramStateRef State) const {
+  static constexpr char SizeGreaterThanBufferSize[] =

alejandro-alvarez-sonarsource wrote:

Now it uses `llvm:StringLiteral`, but I think it (relatively) is. Most existing 
uses of `constexpr llvm::StringLiteral` in llvm are with `static`. And, IIUC, 
without `static`, the variable is going to live on the stack and be created 
each time (even though its value was already computed at compile time).

Probably a moot point, though, since this is not part of a hotpath. For 
consistency with other uses, I'd rather keep it, though.

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


[clang] [clang][analyzer] Model more getline/getdelim pre and postconditions (PR #83027)

2024-03-21 Thread Alejandro Álvarez Ayllón via cfe-commits


@@ -1204,6 +1204,20 @@ void StreamChecker::evalGetdelim(const FnDescription 
*Desc,
 State->BindExpr(E.CE, C.getLocationContext(), RetVal);
 StateNotFailed =
 E.assumeBinOpNN(StateNotFailed, BO_GE, RetVal, E.getZeroVal(Call));
+// The buffer size `*n` must be enough to hold the whole line, and
+// greater than the return value, since it has to account for '\0'.
+auto SizePtrSval = Call.getArgSVal(1);

alejandro-alvarez-sonarsource wrote:

Changed.

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


[clang] a29e9e3 - [clang-format] Add --fail-on-incomplete-format. (#84346)

2024-03-21 Thread via cfe-commits

Author: Roberto Bampi
Date: 2024-03-21T01:29:25-07:00
New Revision: a29e9e32c50273abffc53e3700bbc23985f0a7af

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

LOG: [clang-format] Add --fail-on-incomplete-format. (#84346)

At the moment clang-format will return exit code 0 on incomplete
results. In scripts it would sometimes be useful if clang-format would
instead fail in those cases, signalling that there was something wrong
with the code being formatted.

-

Co-authored-by: Björn Schäpers 
Co-authored-by: Owen Pan 

Added: 
clang/test/Format/fail-on-incomplete.cpp

Modified: 
clang/docs/ClangFormat.rst
clang/tools/clang-format/ClangFormat.cpp

Removed: 




diff  --git a/clang/docs/ClangFormat.rst b/clang/docs/ClangFormat.rst
index 819d9ee9f9cde1..80dc38a075c8fc 100644
--- a/clang/docs/ClangFormat.rst
+++ b/clang/docs/ClangFormat.rst
@@ -61,6 +61,7 @@ to format C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# 
code.
 --dry-run  - If set, do not actually make the 
formatting changes
 --dump-config  - Dump configuration options to stdout and 
exit.
  Can be used with -style option.
+--fail-on-incomplete-format- If set, fail with exit code 1 on 
incomplete format.
 --fallback-style=  - The name of the predefined style used as a
  fallback in case clang-format is invoked 
with
  -style=file, but can not find the 
.clang-format

diff  --git a/clang/test/Format/fail-on-incomplete.cpp 
b/clang/test/Format/fail-on-incomplete.cpp
new file mode 100644
index 00..ccd77af4d59947
--- /dev/null
+++ b/clang/test/Format/fail-on-incomplete.cpp
@@ -0,0 +1,4 @@
+// RUN: not clang-format -style=LLVM -fail-on-incomplete-format %s
+// RUN: clang-format -style=LLVM %s
+
+int a(

diff  --git a/clang/tools/clang-format/ClangFormat.cpp 
b/clang/tools/clang-format/ClangFormat.cpp
index e122cea50f7268..ed401135ad8433 100644
--- a/clang/tools/clang-format/ClangFormat.cpp
+++ b/clang/tools/clang-format/ClangFormat.cpp
@@ -205,6 +205,11 @@ static cl::list FileNames(cl::Positional,
cl::desc("[@] [ ...]"),
cl::cat(ClangFormatCategory));
 
+static cl::opt FailOnIncompleteFormat(
+"fail-on-incomplete-format",
+cl::desc("If set, fail with exit code 1 on incomplete format."),
+cl::init(false), cl::cat(ClangFormatCategory));
+
 namespace clang {
 namespace format {
 
@@ -399,7 +404,7 @@ class ClangFormatDiagConsumer : public DiagnosticConsumer {
 };
 
 // Returns true on error.
-static bool format(StringRef FileName) {
+static bool format(StringRef FileName, bool ErrorOnIncompleteFormat = false) {
   const bool IsSTDIN = FileName == "-";
   if (!OutputXML && Inplace && IsSTDIN) {
 errs() << "error: cannot use -i when reading from stdin.\n";
@@ -535,7 +540,7 @@ static bool format(StringRef FileName) {
   Rewrite.getEditBuffer(ID).write(outs());
 }
   }
-  return false;
+  return ErrorOnIncompleteFormat && !Status.FormatComplete;
 }
 
 } // namespace format
@@ -699,7 +704,7 @@ int main(int argc, const char **argv) {
   }
 
   if (FileNames.empty())
-return clang::format::format("-");
+return clang::format::format("-", FailOnIncompleteFormat);
 
   if (FileNames.size() > 1 &&
   (!Offsets.empty() || !Lengths.empty() || !LineRanges.empty())) {
@@ -717,7 +722,7 @@ int main(int argc, const char **argv) {
   errs() << "Formatting [" << FileNo++ << "/" << FileNames.size() << "] "
  << FileName << "\n";
 }
-Error |= clang::format::format(FileName);
+Error |= clang::format::format(FileName, FailOnIncompleteFormat);
   }
   return Error ? 1 : 0;
 }



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


[clang] [clang][RISCV] Enable RVV with function attribute __attribute__((target("arch=+v"))) (PR #83674)

2024-03-21 Thread Luke Lau via cfe-commits


@@ -8927,8 +8927,13 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
 }
   }
 
-  if (T->isRVVSizelessBuiltinType())
-checkRVVTypeSupport(T, NewVD->getLocation(), cast(CurContext));
+  if (T->isRVVSizelessBuiltinType() && isa(CurContext)) {
+const FunctionDecl *FD = cast(CurContext);
+llvm::StringMap CallerFeatureMap;
+Context.getFunctionFeatureMap(CallerFeatureMap, FD);

lukel97 wrote:

> > @4vtomat if the MCPU has a feature but the function explicitly disables it 
> > then I think we want the `-`
> 
> Why don't we just remove it from feature map?

We also need the negative extensions if the target attribute string is a 
complete arch, e.g. `__attribute__((target="arch=rv64i")))`, because any 
extensions from mcpu need to be turned off.

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


[clang] [clang-format] Add --fail-on-incomplete-format. (PR #84346)

2024-03-21 Thread via cfe-commits

github-actions[bot] wrote:



@gigaroby Congratulations on having your first Pull Request (PR) merged into 
the LLVM Project!

Your changes will be combined with recent changes from other authors, then 
tested
by our [build bots](https://lab.llvm.org/buildbot/). If there is a problem with 
a build, you may recieve a report in an email or a comment on this PR.

Please check whether problems have been caused by your change specifically, as
the builds can include changes from many authors. It is not uncommon for your
change to be included in a build that fails due to someone else's changes, or
infrastructure issues.

How to do this, and the rest of the post-merge process, is covered in detail 
[here](https://llvm.org/docs/MyFirstTypoFix.html#myfirsttypofix-issues-after-landing-your-pr).

If your change does cause a problem, it may be reverted, or you can revert it 
yourself.
This is a normal part of [LLVM 
development](https://llvm.org/docs/DeveloperPolicy.html#patch-reversion-policy).
 You can fix your changes and open a new PR to merge them again.

If you don't get any reports, no action is required from you. Your changes are 
working as expected, well done!


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


[clang] [clang-format] Add --fail-on-incomplete-format. (PR #84346)

2024-03-21 Thread Owen Pan via cfe-commits

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


[clang] [llvm] [WebAssembly] Implement an alternative translation for -wasm-enable-sjlj (PR #84137)

2024-03-21 Thread Heejin Ahn via cfe-commits

aheejin wrote:

@yamt Given that this PR is not large and we already went through it anyway, 
nevermind what I said about rebasing, and please use whatever method you are 
convenient with. But just FYI  you can do `git merge` to avoid rebasing (I'm 
not asking you to do it here; just in case you aren't aware)

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


[clang] [llvm] [InstCombine] Canonicalize `(sitofp x)` -> `(uitofp x)` if `x >= 0` (PR #82404)

2024-03-21 Thread Craig Topper via cfe-commits

topperc wrote:

> > Apart from the correctness issues, we've seen some regressions on various 
> > benchmarks from LLVM Test Suite after this patch. Specifically, around 3-5% 
> > regression on x86-64 in various metrics of the 
> > [Interpolation](https://github.com/llvm/llvm-test-suite/tree/main/MicroBenchmarks/ImageProcessing/Interpolation)
> >  benchmarks, and up to 30% regression on a number of floating point-centric 
> > benchmarks from 
> > https://github.com/llvm/llvm-test-suite/tree/main/SingleSource/Benchmarks/Misc
> >  (flops-4.c, flops-5.c, flops-6.c, flops-8.c, fp-convert.c). The numbers 
> > vary depending on the microarchitecture, with Skylake being less affected 
> > (on the order of ~10%) and AMD Rome showing larger regressions (up to 30%).
> 
> FYI this patch saves ~3% instructions for some benchmarks from 
> LLVM-test-suite on RISC-V. 
> [dtcxzyw/llvm-ci#1115](https://github.com/dtcxzyw/llvm-ci/issues/1115) 
> [dtcxzyw/llvm-ci#1114](https://github.com/dtcxzyw/llvm-ci/issues/1114)

Are you able to extract a reproducer that I can look at?

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


[clang] [RISCV][FMV] Support target_clones (PR #85786)

2024-03-21 Thread Piyou Chen via cfe-commits

BeMg wrote:

The proposal can be found at the 
https://github.com/riscv-non-isa/riscv-c-api-doc/pull/48.

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


[clang] [RISCV][FMV] Support target_clones (PR #85786)

2024-03-21 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-risc-v

Author: Piyou Chen (BeMg)


Changes

This patch enable the function multiversion(FMV) and `target_clones` attribute 
for RISC-V target. 

It will emit the IFUNC resolver function to select appropriate function during 
runtime.

---

Patch is 31.07 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/85786.diff


12 Files Affected:

- (modified) clang/include/clang/Basic/TargetInfo.h (+2-1) 
- (modified) clang/lib/AST/ASTContext.cpp (+9) 
- (modified) clang/lib/Basic/Targets/RISCV.cpp (+8-2) 
- (modified) clang/lib/Basic/Targets/RISCV.h (+2) 
- (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+101-1) 
- (modified) clang/lib/CodeGen/CodeGenFunction.h (+3) 
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+2) 
- (modified) clang/lib/CodeGen/Targets/RISCV.cpp (+23) 
- (modified) clang/lib/Sema/SemaDeclAttr.cpp (+22) 
- (added) clang/test/CodeGen/attr-target-clones-riscv.c (+135) 
- (added) clang/test/CodeGenCXX/attr-target-clones-riscv.cpp (+136) 
- (added) clang/test/SemaCXX/attr-target-clones-riscv.cpp (+28) 


``diff
diff --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 374595edd2ce4a..aa48596fbce07d 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1445,7 +1445,8 @@ class TargetInfo : public TransferrableTargetInfo,
   /// Identify whether this target supports multiversioning of functions,
   /// which requires support for cpu_supports and cpu_is functionality.
   bool supportsMultiVersioning() const {
-return getTriple().isX86() || getTriple().isAArch64();
+return getTriple().isX86() || getTriple().isAArch64() ||
+   getTriple().isRISCV();
   }
 
   /// Identify whether this target supports IFuncs.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 5a8fae76a43a4d..0fd75e0b36b123 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -13636,6 +13636,15 @@ void 
ASTContext::getFunctionFeatureMap(llvm::StringMap ,
   Features.insert(Features.begin(),
   Target->getTargetOpts().FeaturesAsWritten.begin(),
   Target->getTargetOpts().FeaturesAsWritten.end());
+} else if (Target->getTriple().isRISCV()) {
+  if (VersionStr != "default") {
+ParsedTargetAttr ParsedAttr = Target->parseTargetAttr(VersionStr);
+Features.insert(Features.begin(), ParsedAttr.Features.begin(),
+ParsedAttr.Features.end());
+  }
+  Features.insert(Features.begin(),
+  Target->getTargetOpts().FeaturesAsWritten.begin(),
+  Target->getTargetOpts().FeaturesAsWritten.end());
 } else {
   if (VersionStr.starts_with("arch="))
 TargetCPU = VersionStr.drop_front(sizeof("arch=") - 1);
diff --git a/clang/lib/Basic/Targets/RISCV.cpp 
b/clang/lib/Basic/Targets/RISCV.cpp
index a6d4af2b88111a..8e9132c9191a3c 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -257,7 +257,7 @@ bool RISCVTargetInfo::initFeatureMap(
 
   // If a target attribute specified a full arch string, override all the ISA
   // extension target features.
-  const auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride");
+  const auto I = llvm::find(FeaturesVec, "+__RISCV_TargetAttrNeedOverride");
   if (I != FeaturesVec.end()) {
 std::vector OverrideFeatures(std::next(I), FeaturesVec.end());
 
@@ -366,6 +366,12 @@ bool 
RISCVTargetInfo::handleTargetFeatures(std::vector ,
   return true;
 }
 
+bool RISCVTargetInfo::isValidFeatureName(StringRef Feature) const {
+  if (Feature.starts_with("__RISCV_TargetAttrNeedOverride"))
+return true;
+  return llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature);
+}
+
 bool RISCVTargetInfo::isValidCPUName(StringRef Name) const {
   bool Is64Bit = getTriple().isArch64Bit();
   return llvm::RISCV::parseCPU(Name, Is64Bit);
@@ -390,7 +396,7 @@ void RISCVTargetInfo::fillValidTuneCPUList(
 
 static void handleFullArchString(StringRef FullArchStr,
  std::vector ) {
-  Features.push_back("__RISCV_TargetAttrNeedOverride");
+  Features.push_back("+__RISCV_TargetAttrNeedOverride");
   auto RII = llvm::RISCVISAInfo::parseArchString(
   FullArchStr, /* EnableExperimentalExtension */ true);
   if (llvm::errorToBool(RII.takeError())) {
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index bfbdafb682c851..ef8f59185d753c 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -106,6 +106,8 @@ class RISCVTargetInfo : public TargetInfo {
   bool handleTargetFeatures(std::vector ,
 DiagnosticsEngine ) override;
 
+  bool isValidFeatureName(StringRef Feature) const override;
+
   bool hasBitIntType() const override { return true; }
 
   bool hasBFloat16Type() const 

[clang] [RISCV][FMV] Support target_clones (PR #85786)

2024-03-21 Thread Piyou Chen via cfe-commits

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


[clang] [RISCV][FMV] Support target_clones (PR #85786)

2024-03-21 Thread Piyou Chen via cfe-commits

https://github.com/BeMg updated https://github.com/llvm/llvm-project/pull/85786

>From 239b404203c66ab5336ffdfb45969a50c439a1c0 Mon Sep 17 00:00:00 2001
From: Piyou Chen 
Date: Tue, 19 Mar 2024 06:22:17 -0700
Subject: [PATCH 1/2] [RISCV][FMV] Support target_clones

---
 clang/include/clang/Basic/TargetInfo.h|   3 +-
 clang/lib/AST/ASTContext.cpp  |   9 ++
 clang/lib/Basic/Targets/RISCV.cpp |  10 +-
 clang/lib/Basic/Targets/RISCV.h   |   2 +
 clang/lib/CodeGen/CodeGenFunction.cpp | 102 -
 clang/lib/CodeGen/CodeGenFunction.h   |   3 +
 clang/lib/CodeGen/CodeGenModule.cpp   |   2 +
 clang/lib/CodeGen/Targets/RISCV.cpp   |  23 +++
 clang/lib/Sema/SemaDeclAttr.cpp   |  22 +++
 clang/test/CodeGen/attr-target-clones-riscv.c | 135 +
 .../CodeGenCXX/attr-target-clones-riscv.cpp   | 136 ++
 .../test/SemaCXX/attr-target-clones-riscv.cpp |  19 +++
 12 files changed, 462 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGen/attr-target-clones-riscv.c
 create mode 100644 clang/test/CodeGenCXX/attr-target-clones-riscv.cpp
 create mode 100644 clang/test/SemaCXX/attr-target-clones-riscv.cpp

diff --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 374595edd2ce4a..aa48596fbce07d 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1445,7 +1445,8 @@ class TargetInfo : public TransferrableTargetInfo,
   /// Identify whether this target supports multiversioning of functions,
   /// which requires support for cpu_supports and cpu_is functionality.
   bool supportsMultiVersioning() const {
-return getTriple().isX86() || getTriple().isAArch64();
+return getTriple().isX86() || getTriple().isAArch64() ||
+   getTriple().isRISCV();
   }
 
   /// Identify whether this target supports IFuncs.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 5a8fae76a43a4d..0fd75e0b36b123 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -13636,6 +13636,15 @@ void 
ASTContext::getFunctionFeatureMap(llvm::StringMap ,
   Features.insert(Features.begin(),
   Target->getTargetOpts().FeaturesAsWritten.begin(),
   Target->getTargetOpts().FeaturesAsWritten.end());
+} else if (Target->getTriple().isRISCV()) {
+  if (VersionStr != "default") {
+ParsedTargetAttr ParsedAttr = Target->parseTargetAttr(VersionStr);
+Features.insert(Features.begin(), ParsedAttr.Features.begin(),
+ParsedAttr.Features.end());
+  }
+  Features.insert(Features.begin(),
+  Target->getTargetOpts().FeaturesAsWritten.begin(),
+  Target->getTargetOpts().FeaturesAsWritten.end());
 } else {
   if (VersionStr.starts_with("arch="))
 TargetCPU = VersionStr.drop_front(sizeof("arch=") - 1);
diff --git a/clang/lib/Basic/Targets/RISCV.cpp 
b/clang/lib/Basic/Targets/RISCV.cpp
index a6d4af2b88111a..8e9132c9191a3c 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -257,7 +257,7 @@ bool RISCVTargetInfo::initFeatureMap(
 
   // If a target attribute specified a full arch string, override all the ISA
   // extension target features.
-  const auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride");
+  const auto I = llvm::find(FeaturesVec, "+__RISCV_TargetAttrNeedOverride");
   if (I != FeaturesVec.end()) {
 std::vector OverrideFeatures(std::next(I), FeaturesVec.end());
 
@@ -366,6 +366,12 @@ bool 
RISCVTargetInfo::handleTargetFeatures(std::vector ,
   return true;
 }
 
+bool RISCVTargetInfo::isValidFeatureName(StringRef Feature) const {
+  if (Feature.starts_with("__RISCV_TargetAttrNeedOverride"))
+return true;
+  return llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature);
+}
+
 bool RISCVTargetInfo::isValidCPUName(StringRef Name) const {
   bool Is64Bit = getTriple().isArch64Bit();
   return llvm::RISCV::parseCPU(Name, Is64Bit);
@@ -390,7 +396,7 @@ void RISCVTargetInfo::fillValidTuneCPUList(
 
 static void handleFullArchString(StringRef FullArchStr,
  std::vector ) {
-  Features.push_back("__RISCV_TargetAttrNeedOverride");
+  Features.push_back("+__RISCV_TargetAttrNeedOverride");
   auto RII = llvm::RISCVISAInfo::parseArchString(
   FullArchStr, /* EnableExperimentalExtension */ true);
   if (llvm::errorToBool(RII.takeError())) {
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index bfbdafb682c851..ef8f59185d753c 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -106,6 +106,8 @@ class RISCVTargetInfo : public TargetInfo {
   bool handleTargetFeatures(std::vector ,
 DiagnosticsEngine ) override;
 
+  bool isValidFeatureName(StringRef Feature) const 

[clang] [Clang][Sema]: Allow flexible arrays in unions and alone in structs (PR #84428)

2024-03-21 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

> because we don't yet support non-zero initialization (as described in commit 
> [5955a0f](https://github.com/llvm/llvm-project/commit/5955a0f9375a8c0b134eeb4a8de5155dcce7c94f))

I'm confused.  We support non-zero init, and there are tests for non-zero init 
in that commit. The commit message mentions dynamic initialization, but that's 
not non-zero; that's "requires code to run at program startup".

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


[clang] [llvm] [PowerPC] Tune AIX shared library TLS model at function level by heuristic (PR #84132)

2024-03-21 Thread Kai Luo via cfe-commits


@@ -329,6 +329,12 @@ def FeatureAIXLocalExecTLS :
"Produce a TOC-free local-exec TLS sequence for this 
function "
"for 64-bit AIX">;
 
+def FeatureAIXSharedLibraryTLSModelHeuristic :
+  SubtargetFeature<"aix-shared-library-tls-model-heuristic",

bzEq wrote:

This should be an optimization, maybe rename to 
`aix-shared-library-tls-model-opt`, we perform optimization based on some 
heuristics.

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


[clang] [clang] move -Wcast-function-type under -Wextra (PR #77178)

2024-03-21 Thread Abhin P Jose via cfe-commits

Abhinkop wrote:

> I believe this patch is causing some issues on two PPC bots. Would you be 
> able to help take a look? 
> https://lab.llvm.org/buildbot/#/builders/57/builds/33601/steps/5/logs/stdio 
> https://lab.llvm.org/buildbot/#/builders/36/builds/43759/steps/12/logs/stdio

I guess adding this flag (-Wno-cast-function-type-strict) will make the error 
go away. But it is caused by the conversion of the second argument "void*" to 
"siginfo_t *" when casting from "SignalHandlerType" i.e. "void 
(*__sanitizer::SignalHandlerType)(int, void *, void *);" to "void 
(*sa_sigaction) (int, siginfo_t *, void *);". If you are sure that this 
conversion is valid, I guess we can add this file. Might be similar for others.

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


[clang] [llvm] [PowerPC] Tune AIX shared library TLS model at function level by heuristic (PR #84132)

2024-03-21 Thread Kai Luo via cfe-commits


@@ -3369,6 +3369,48 @@ SDValue 
PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
   bool Is64Bit = Subtarget.isPPC64();
   bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
   TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
+  // Initialize heuristic setting lazily:
+  // (1) Use initial-exec for single TLS var reference within current function.
+  // (2) Use local-dynamic for multiple TLS var references within current func.
+  PPCFunctionInfo *FuncInfo =
+  DAG.getMachineFunction().getInfo();
+  if (Subtarget.hasAIXShLibTLSModelHeuristic() &&
+  !FuncInfo->isAIXFuncUseInitDone()) {
+std::set TLSGV;

bzEq wrote:

```suggestion
SmallPtrSet TLSGV;
```

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


[clang] [llvm] [PowerPC] Tune AIX shared library TLS model at function level by heuristic (PR #84132)

2024-03-21 Thread Kai Luo via cfe-commits


@@ -3369,6 +3369,48 @@ SDValue 
PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
   bool Is64Bit = Subtarget.isPPC64();
   bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
   TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
+  // Initialize heuristic setting lazily:
+  // (1) Use initial-exec for single TLS var reference within current function.
+  // (2) Use local-dynamic for multiple TLS var references within current func.
+  PPCFunctionInfo *FuncInfo =
+  DAG.getMachineFunction().getInfo();
+  if (Subtarget.hasAIXShLibTLSModelHeuristic() &&
+  !FuncInfo->isAIXFuncUseInitDone()) {
+std::set TLSGV;
+for (SDNode  : DAG.allnodes()) {

bzEq wrote:

One DAG is mapped to a single basic block, I notice your description is about 
whole function. So the size of `TLSGV` is smaller than what you really want to 
count.

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


[clang] [clang-format] Add --fail-on-incomplete-format. (PR #84346)

2024-03-21 Thread Owen Pan via cfe-commits

https://github.com/owenca updated 
https://github.com/llvm/llvm-project/pull/84346

>From e19f49ca2660cbcd64fb81aae0428e899d61cac6 Mon Sep 17 00:00:00 2001
From: Roberto Bampi 
Date: Thu, 7 Mar 2024 18:10:56 +0100
Subject: [PATCH 1/3] [clang-format] Add --fail-on-incomplete-format.

At the moment clang-format will return exit code 0 on incomplete
results. In scripts it would sometimes be useful if clang-format would
instead fail in those cases, signalling that there was something wrong
with the code being formatted.
---
 clang/docs/ClangFormat.rst   |  1 +
 clang/test/Format/fail-on-incomplete.cpp |  4 
 clang/tools/clang-format/ClangFormat.cpp | 14 +++---
 3 files changed, 16 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Format/fail-on-incomplete.cpp

diff --git a/clang/docs/ClangFormat.rst b/clang/docs/ClangFormat.rst
index 819d9ee9f9cde1..80dc38a075c8fc 100644
--- a/clang/docs/ClangFormat.rst
+++ b/clang/docs/ClangFormat.rst
@@ -61,6 +61,7 @@ to format C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# 
code.
 --dry-run  - If set, do not actually make the 
formatting changes
 --dump-config  - Dump configuration options to stdout and 
exit.
  Can be used with -style option.
+--fail-on-incomplete-format- If set, fail with exit code 1 on 
incomplete format.
 --fallback-style=  - The name of the predefined style used as a
  fallback in case clang-format is invoked 
with
  -style=file, but can not find the 
.clang-format
diff --git a/clang/test/Format/fail-on-incomplete.cpp 
b/clang/test/Format/fail-on-incomplete.cpp
new file mode 100644
index 00..42ddea66faf6ee
--- /dev/null
+++ b/clang/test/Format/fail-on-incomplete.cpp
@@ -0,0 +1,4 @@
+// RUN: not clang-format %s -style=LLVM -fail-on-incomplete-format
+// RUN: clang-format %s -style=LLVM
+int a(
+
diff --git a/clang/tools/clang-format/ClangFormat.cpp 
b/clang/tools/clang-format/ClangFormat.cpp
index e122cea50f7268..58027af5d9e091 100644
--- a/clang/tools/clang-format/ClangFormat.cpp
+++ b/clang/tools/clang-format/ClangFormat.cpp
@@ -205,6 +205,11 @@ static cl::list FileNames(cl::Positional,
cl::desc("[@] [ ...]"),
cl::cat(ClangFormatCategory));
 
+static cl::opt FailOnIncompleteFormat(
+"fail-on-incomplete-format",
+cl::desc("If set, fail with exit code 1 on incomplete format."),
+cl::init(false), cl::cat(ClangFormatCategory));
+
 namespace clang {
 namespace format {
 
@@ -399,7 +404,7 @@ class ClangFormatDiagConsumer : public DiagnosticConsumer {
 };
 
 // Returns true on error.
-static bool format(StringRef FileName) {
+static bool format(StringRef FileName, bool ErrorOnIncompleteFormat = false) {
   const bool IsSTDIN = FileName == "-";
   if (!OutputXML && Inplace && IsSTDIN) {
 errs() << "error: cannot use -i when reading from stdin.\n";
@@ -535,6 +540,9 @@ static bool format(StringRef FileName) {
   Rewrite.getEditBuffer(ID).write(outs());
 }
   }
+  if (ErrorOnIncompleteFormat && !Status.FormatComplete)
+return true;
+
   return false;
 }
 
@@ -699,7 +707,7 @@ int main(int argc, const char **argv) {
   }
 
   if (FileNames.empty())
-return clang::format::format("-");
+return clang::format::format("-", FailOnIncompleteFormat);
 
   if (FileNames.size() > 1 &&
   (!Offsets.empty() || !Lengths.empty() || !LineRanges.empty())) {
@@ -717,7 +725,7 @@ int main(int argc, const char **argv) {
   errs() << "Formatting [" << FileNo++ << "/" << FileNames.size() << "] "
  << FileName << "\n";
 }
-Error |= clang::format::format(FileName);
+Error |= clang::format::format(FileName, FailOnIncompleteFormat);
   }
   return Error ? 1 : 0;
 }

>From af442672b7957593d37a1640b316fa4d8ec00467 Mon Sep 17 00:00:00 2001
From: Roberto Bampi 
Date: Fri, 8 Mar 2024 14:51:49 +0100
Subject: [PATCH 2/3] Update clang/tools/clang-format/ClangFormat.cpp
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Björn Schäpers 
---
 clang/tools/clang-format/ClangFormat.cpp | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/clang/tools/clang-format/ClangFormat.cpp 
b/clang/tools/clang-format/ClangFormat.cpp
index 58027af5d9e091..ed401135ad8433 100644
--- a/clang/tools/clang-format/ClangFormat.cpp
+++ b/clang/tools/clang-format/ClangFormat.cpp
@@ -540,10 +540,7 @@ static bool format(StringRef FileName, bool 
ErrorOnIncompleteFormat = false) {
   Rewrite.getEditBuffer(ID).write(outs());
 }
   }
-  if (ErrorOnIncompleteFormat && !Status.FormatComplete)
-return true;
-
-  return false;
+  return ErrorOnIncompleteFormat && !Status.FormatComplete;
 }
 
 } // namespace format

>From f181f24ef9dff3d978eaa13aae273f670cbdaaa8 Mon Sep 17 00:00:00 2001

[clang] [Clang][Sema]: Allow flexible arrays in unions and alone in structs (PR #84428)

2024-03-21 Thread Kees Cook via cfe-commits

https://github.com/kees updated https://github.com/llvm/llvm-project/pull/84428

>From eb5138b45fa450737600050ad8dabdcb27513d42 Mon Sep 17 00:00:00 2001
From: Kees Cook 
Date: Thu, 7 Mar 2024 17:03:09 -0800
Subject: [PATCH 1/6] [Clang][Sema]: Allow flexible arrays in unions and alone
 in structs

GNU and MSVC have extensions where flexible array members (or their
equivalent) can be in unions or alone in structs. This is already fully
supported in Clang through the 0-sized array ("fake flexible array")
extension or when C99 flexible array members have been syntactically
obfuscated.

Clang needs to explicitly allow these extensions directly for C99
flexible arrays, since they are common code patterns in active use by the
Linux kernel (and other projects). Such projects have been using either
0-sized arrays (which is considered deprecated in favor of C99 flexible
array members) or via obfuscated syntax, both of which complicate their
code bases.

For example, these do not error by default:

union one {
int a;
int b[0];
};

union two {
int a;
struct {
struct { } __empty;
int b[];
};
};

But this does:

union three {
int a;
int b[];
};

Remove the default error diagnostics for this but continue to provide
warnings under Microsoft or GNU extensions checks. This will allow for
a seamless transition for code bases away from 0-sized arrays without
losing existing code patterns. Add explicit checking for the warnings
under various constructions.

Fixes #84565
---
 clang/docs/ReleaseNotes.rst   |  3 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  5 --
 clang/lib/Sema/SemaDecl.cpp   |  8 +--
 clang/test/C/drs/dr5xx.c  |  2 +-
 clang/test/Sema/flexible-array-in-union.c | 53 +--
 clang/test/Sema/transparent-union.c   |  4 +-
 6 files changed, 57 insertions(+), 18 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1b901a27fd19d1..960ab7e021cf2f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -214,6 +214,9 @@ Improvements to Clang's diagnostics
 - Clang now diagnoses lambda function expressions being implicitly cast to 
boolean values, under ``-Wpointer-bool-conversion``.
   Fixes #GH82512.
 
+- ``-Wmicrosoft`` or ``-Wgnu`` is now required to diagnose C99 flexible
+  array members in a union or alone in a struct.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c8dfdc08f5ea07..f09121b8c7ec8f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6447,9 +6447,6 @@ def ext_c99_flexible_array_member : Extension<
 def err_flexible_array_virtual_base : Error<
   "flexible array member %0 not allowed in "
   "%select{struct|interface|union|class|enum}1 which has a virtual base 
class">;
-def err_flexible_array_empty_aggregate : Error<
-  "flexible array member %0 not allowed in otherwise empty "
-  "%select{struct|interface|union|class|enum}1">;
 def err_flexible_array_has_nontrivial_dtor : Error<
   "flexible array member %0 of type %1 with non-trivial destruction">;
 def ext_flexible_array_in_struct : Extension<
@@ -6464,8 +6461,6 @@ def ext_flexible_array_empty_aggregate_ms : Extension<
   "flexible array member %0 in otherwise empty "
   "%select{struct|interface|union|class|enum}1 is a Microsoft extension">,
   InGroup;
-def err_flexible_array_union : Error<
-  "flexible array member %0 in a union is not allowed">;
 def ext_flexible_array_union_ms : Extension<
   "flexible array member %0 in a union is a Microsoft extension">,
   InGroup;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 67e56a917a51de..053122b588246b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -19357,15 +19357,11 @@ void Sema::ActOnFields(Scope *S, SourceLocation 
RecLoc, Decl *EnclosingDecl,
 } else if (Record->isUnion())
   DiagID = getLangOpts().MicrosoftExt
? diag::ext_flexible_array_union_ms
-   : getLangOpts().CPlusPlus
- ? diag::ext_flexible_array_union_gnu
- : diag::err_flexible_array_union;
+   : diag::ext_flexible_array_union_gnu;
 else if (NumNamedMembers < 1)
   DiagID = getLangOpts().MicrosoftExt
? diag::ext_flexible_array_empty_aggregate_ms
-   : getLangOpts().CPlusPlus
- ? diag::ext_flexible_array_empty_aggregate_gnu
- : diag::err_flexible_array_empty_aggregate;
+   : diag::ext_flexible_array_empty_aggregate_gnu;
 
 if (DiagID)
   

[clang] [Clang][Sema]: Allow flexible arrays in unions and alone in structs (PR #84428)

2024-03-21 Thread Kees Cook via cfe-commits

kees wrote:

> `InitListChecker::CheckStructUnionTypes` never calls 
> `StructuredList->setInitializedFieldInUnion`

Ah-ha, thank you for the pointer. I think I've figured this out: initialization 
was avoiding flexible arrays because we don't yet support non-zero 
initialization (as described in commit 
5955a0f9375a8c0b134eeb4a8de5155dcce7c94f). However, we _do_ want to allow zero 
initialization. This fixes the Assert and the sketchy `undef`s in the codegen 
output. Now we get zero inits:

```diff
-// If we've hit the flexible array member at the end, we're done.
-if (Field->getType()->isIncompleteArrayType())
+// If we've hit a flexible array member, only allow zero initialization.
+// Other values are not yet supported. See commit 5955a0f9375a.
+if (Field->getType()->isIncompleteArrayType() && !IsZeroInitializer(Init))
```

> I think things can be simplified a bit further

Ah yes! That's much nicer. Since we're processing the Union, we can just return 
completely instead of continuing the loop. Thanks!


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


[clang] [clang-format] Add --fail-on-incomplete-format. (PR #84346)

2024-03-21 Thread Owen Pan via cfe-commits

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


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


[clang] [clang-format] Add --fail-on-incomplete-format. (PR #84346)

2024-03-21 Thread Owen Pan via cfe-commits


@@ -0,0 +1,5 @@
+// RUN: cat %s | not clang-format --fail-on-incomplete-format | FileCheck %s
+// RUN: cat %s | clang-format | FileCheck %s
+int a([) {}
+
+// CHECK: int a([) {}

owenca wrote:

> Done. It took me quite a while but `-style=LLVM` is also required as the 
> .clang-format in the parent directory sets DisableFormat to true. Before I 
> didn't notice because the `cat %s | clang-format` was bypassing the lookup 
> for the config file.

It seems that `-style=LLVM` is needed whether the input comes from the stdin or 
a file.

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


[clang] [llvm] [PowerPC] Tune AIX shared library TLS model at function level by heuristic (PR #84132)

2024-03-21 Thread Kai Luo via cfe-commits


@@ -80,6 +80,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public 
TargetInfo {
   bool IsISA3_0 = false;
   bool IsISA3_1 = false;
   bool HasQuadwordAtomics = false;
+  bool HasAIXShLibTLSModelHeuristic = false;

bzEq wrote:

This looks redundant. Frontend doesn't read this flag to change behavior.

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


[clang] [llvm] [InstCombine] Canonicalize `(sitofp x)` -> `(uitofp x)` if `x >= 0` (PR #82404)

2024-03-21 Thread Yingwei Zheng via cfe-commits

dtcxzyw wrote:

> Apart from the correctness issues, we've seen some regressions on various 
> benchmarks from LLVM Test Suite after this patch. Specifically, around 3-5% 
> regression on x86-64 in various metrics of the 
> [Interpolation](https://github.com/llvm/llvm-test-suite/tree/main/MicroBenchmarks/ImageProcessing/Interpolation)
>  benchmarks, and up to 30% regression on a number of floating point-centric 
> benchmarks from 
> https://github.com/llvm/llvm-test-suite/tree/main/SingleSource/Benchmarks/Misc
>  (flops-4.c, flops-5.c, flops-6.c, flops-8.c, fp-convert.c). The numbers vary 
> depending on the microarchitecture, with Skylake being less affected (on the 
> order of ~10%) and AMD Rome showing larger regressions (up to 30%).

FYI this patch saves ~3% instructions for some benchmarks from LLVM-test-suite 
on RISC-V.
https://github.com/dtcxzyw/llvm-ci/issues/1115
https://github.com/dtcxzyw/llvm-ci/issues/1114

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


<    1   2   3   4