[llvm-branch-commits] [BOLT] Invoke terminator (PR #148333)
https://github.com/aaupov edited https://github.com/llvm/llvm-project/pull/148333 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [BOLT] Invoke terminator (PR #148333)
https://github.com/aaupov created https://github.com/llvm/llvm-project/pull/148333 None ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] f1cc3ea - Revert "[clang] [ubsan] add __has_feature for UBSan checks (#148310)"
Author: Florian Mayer Date: 2025-07-11T18:01:09-07:00 New Revision: f1cc3eaf2707726d86efbb651478d7310b8a3840 URL: https://github.com/llvm/llvm-project/commit/f1cc3eaf2707726d86efbb651478d7310b8a3840 DIFF: https://github.com/llvm/llvm-project/commit/f1cc3eaf2707726d86efbb651478d7310b8a3840.diff LOG: Revert "[clang] [ubsan] add __has_feature for UBSan checks (#148310)" This reverts commit a7438d6dfe0aa45f3c4f0e0aeb23934619c8702b. Added: Modified: clang/include/clang/Basic/Features.def clang/test/Lexer/has_feature_undefined_behavior_sanitizer.cpp Removed: diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 579461b4f710f..14bff8a68846d 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -54,47 +54,6 @@ FEATURE(memtag_globals, FEATURE(xray_instrument, LangOpts.XRayInstrument) FEATURE(undefined_behavior_sanitizer, LangOpts.Sanitize.hasOneOf(SanitizerKind::Undefined)) -FEATURE(undefined_behavior_sanitizer_finegrained_feature_checks, true) -// These are all part of undefined_behavior_sanitizer: -FEATURE(alignment_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::Alignment)) -FEATURE(bool_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::Bool)) -FEATURE(builtin_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::Builtin)) -FEATURE(array_bounds_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::ArrayBounds)) -FEATURE(enum_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::Enum)) -FEATURE(float_cast_overflow_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::FloatCastOverflow)) -FEATURE(integer_divide_by_zero_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::IntegerDivideByZero)) -FEATURE(nonnull_attribute_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::NonnullAttribute)) -FEATURE(null_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::Null)) -FEATURE(object_size_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::ObjectSize)) -FEATURE(pointer_overflow_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::PointerOverflow)) -FEATURE(return_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::Return)) -FEATURE(returns_nonnull_attribute_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::ReturnsNonnullAttribute)) -FEATURE(shift_base_sanitizer, LangOpts.Sanitize.has(SanitizerKind::ShiftBase)) -FEATURE(shift_exponent_sanitizer, LangOpts.Sanitize.has(SanitizerKind::ShiftExponent)) -FEATURE(shift_sanitizer, -LangOpts.Sanitize.hasOneOf(SanitizerKind::Shift)) -FEATURE(signed_integer_overflow_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::SignedIntegerOverflow)) -FEATURE(unreachable_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::Unreachable)) -FEATURE(vla_bound_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::VLABound)) -FEATURE(function_sanitizer, -LangOpts.Sanitize.has(SanitizerKind::Function)) - FEATURE(realtime_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Realtime)) FEATURE(coverage_sanitizer, LangOpts.SanitizeCoverage) diff --git a/clang/test/Lexer/has_feature_undefined_behavior_sanitizer.cpp b/clang/test/Lexer/has_feature_undefined_behavior_sanitizer.cpp index 257b472e83f3e..62e5316dde58e 100644 --- a/clang/test/Lexer/has_feature_undefined_behavior_sanitizer.cpp +++ b/clang/test/Lexer/has_feature_undefined_behavior_sanitizer.cpp @@ -1,177 +1,13 @@ // RUN: %clang -E -fsanitize=undefined %s -o - | FileCheck --check-prefix=CHECK-UBSAN %s -// RUN: %clang -E -fsanitize=alignment %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-ALIGNMENT %s -// RUN: %clang -E -fsanitize=bool %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-BOOL %s -// RUN: %clang -E -fsanitize=builtin %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-BUILTIN %s -// RUN: %clang -E -fsanitize=array-bounds %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-ARRAY-BOUNDS %s -// RUN: %clang -E -fsanitize=enum %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-ENUM %s -// RUN: %clang -E -fsanitize=float-cast-overflow %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-FLOAT-CAST-OVERFLOW %s -// RUN: %clang -E -fsanitize=integer-divide-by-zero %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-INTEGER-DIVIDE-BY-ZERO %s -// RUN: %clang -E -fsanitize=nonnull-attribute %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-NONNULL-ATTRIBUTE %s -// RUN: %clang -E -fsanitize=null %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-NULL %s -// object-size is a no-op at O0. -// RUN: %clang -E -O2 -fsanitize=object-size %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-OBJECT-SIZE %s -// RUN: %clang -E -fsanitize=pointer-overflow %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-POINTER-OVERFLOW %s -// RUN: %clang -E -fsanitize=return %s -o - | FileCheck --check-pre
[llvm-branch-commits] ELF: Introduce R_AARCH64_PATCHINST relocation type. (PR #133534)
https://github.com/pcc edited https://github.com/llvm/llvm-project/pull/133534 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][RootSignature] Allow for multiple parsing errors in `RootSignatureParser` (PR #147832)
https://github.com/inbelic edited https://github.com/llvm/llvm-project/pull/147832 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][RootSignature] Allow for multiple parsing errors in `RootSignatureParser` (PR #147832)
@@ -27,51 +36,68 @@ RootSignatureParser::RootSignatureParser( bool RootSignatureParser::parse() { // Iterate as many RootSignatureElements as possible, until we hit the // end of the stream + bool HadError = false; inbelic wrote: The pattern that I have seen elsewhere is to use this form, so I shall keep it https://github.com/llvm/llvm-project/pull/147832 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][RootSignature] Allow for multiple parsing errors in `RootSignatureParser` (PR #147832)
https://github.com/inbelic edited https://github.com/llvm/llvm-project/pull/147832 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][RootSignature] Allow for multiple parsing errors in `RootSignatureParser` (PR #147832)
@@ -27,51 +36,68 @@ RootSignatureParser::RootSignatureParser( bool RootSignatureParser::parse() { // Iterate as many RootSignatureElements as possible, until we hit the // end of the stream + bool HadError = false; while (!peekExpectedToken(TokenKind::end_of_stream)) { +bool HadLocalError = false; if (tryConsumeExpectedToken(TokenKind::kw_RootFlags)) { SourceLocation ElementLoc = getTokenLocation(CurToken); auto Flags = parseRootFlags(); - if (!Flags.has_value()) -return true; - Elements.emplace_back(RootSignatureElement(ElementLoc, *Flags)); + if (Flags.has_value()) +Elements.emplace_back(RootSignatureElement(ElementLoc, *Flags)); + else +HadLocalError = true; } else if (tryConsumeExpectedToken(TokenKind::kw_RootConstants)) { SourceLocation ElementLoc = getTokenLocation(CurToken); auto Constants = parseRootConstants(); - if (!Constants.has_value()) -return true; - Elements.emplace_back(RootSignatureElement(ElementLoc, *Constants)); + if (Constants.has_value()) +Elements.emplace_back(RootSignatureElement(ElementLoc, *Constants)); + else +HadLocalError = true; } else if (tryConsumeExpectedToken(TokenKind::kw_DescriptorTable)) { SourceLocation ElementLoc = getTokenLocation(CurToken); auto Table = parseDescriptorTable(); - if (!Table.has_value()) -return true; - Elements.emplace_back(RootSignatureElement(ElementLoc, *Table)); + if (Table.has_value()) +Elements.emplace_back(RootSignatureElement(ElementLoc, *Table)); + else { +HadLocalError = true; +// We are within a DescriptorTable, we will do our best to recover +// by skipping until we encounter the expected closing ')'. +skipUntilExpectedToken(TokenKind::pu_r_paren); inbelic wrote: This is only done on the descriptor table because we want to avoid accidently parsing an element of the descriptor table as a root element. So we need to "exit" the descriptor table scope. For instance: ``` DescriptorTable( SRV(s0, invalid), CBV(b0, numDescriptor = 2) ), UAV(u0) ``` Parsing would fail here on the invalid token. We don't want to keep parsing the CBV as a root element, but we do want to try again starting at UAV. This is done because they have the same token. Typing this out, I realized though that we actually need to skip until it is closed, not just to the next one. Updated for this and added a test-case. https://github.com/llvm/llvm-project/pull/147832 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][RootSignature] Allow for multiple parsing errors in `RootSignatureParser` (PR #147832)
@@ -27,51 +36,68 @@ RootSignatureParser::RootSignatureParser( bool RootSignatureParser::parse() { // Iterate as many RootSignatureElements as possible, until we hit the // end of the stream + bool HadError = false; while (!peekExpectedToken(TokenKind::end_of_stream)) { +bool HadLocalError = false; if (tryConsumeExpectedToken(TokenKind::kw_RootFlags)) { SourceLocation ElementLoc = getTokenLocation(CurToken); auto Flags = parseRootFlags(); - if (!Flags.has_value()) -return true; - Elements.emplace_back(RootSignatureElement(ElementLoc, *Flags)); + if (Flags.has_value()) +Elements.emplace_back(RootSignatureElement(ElementLoc, *Flags)); + else +HadLocalError = true; } else if (tryConsumeExpectedToken(TokenKind::kw_RootConstants)) { SourceLocation ElementLoc = getTokenLocation(CurToken); auto Constants = parseRootConstants(); - if (!Constants.has_value()) -return true; - Elements.emplace_back(RootSignatureElement(ElementLoc, *Constants)); + if (Constants.has_value()) +Elements.emplace_back(RootSignatureElement(ElementLoc, *Constants)); + else +HadLocalError = true; inbelic wrote: I won't apply it here, but I will keep that in mind for the aforementioned clean-up pr https://github.com/llvm/llvm-project/pull/147832 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][RootSignature] Allow for multiple parsing errors in `RootSignatureParser` (PR #147832)
@@ -27,51 +36,68 @@ RootSignatureParser::RootSignatureParser( bool RootSignatureParser::parse() { // Iterate as many RootSignatureElements as possible, until we hit the // end of the stream + bool HadError = false; while (!peekExpectedToken(TokenKind::end_of_stream)) { +bool HadLocalError = false; if (tryConsumeExpectedToken(TokenKind::kw_RootFlags)) { SourceLocation ElementLoc = getTokenLocation(CurToken); auto Flags = parseRootFlags(); - if (!Flags.has_value()) -return true; - Elements.emplace_back(RootSignatureElement(ElementLoc, *Flags)); + if (Flags.has_value()) inbelic wrote: Yep, the prs have been constantly stacked upon each other, so introducing this change in between would be a bit messy. I will wait until the reset is merged in. https://github.com/llvm/llvm-project/pull/147832 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][RootSignature] Allow for multiple parsing errors in `RootSignatureParser` (PR #147832)
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/147832 >From 7ec7e32d2ac4945a489d5463b9fb700b0cceff9d Mon Sep 17 00:00:00 2001 From: Finn Plummer Date: Wed, 9 Jul 2025 21:21:53 + Subject: [PATCH 1/3] [HLSL][RootSignature] Implement multiple diagnostics in `RootSignatureParser` --- .../clang/Parse/ParseHLSLRootSignature.h | 8 ++ clang/lib/Parse/ParseHLSLRootSignature.cpp| 87 ++- clang/test/SemaHLSL/RootSignature-err.hlsl| 38 3 files changed, 113 insertions(+), 20 deletions(-) diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h index 404bccea10c99..9f46158b963f0 100644 --- a/clang/include/clang/Parse/ParseHLSLRootSignature.h +++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h @@ -198,6 +198,14 @@ class RootSignatureParser { bool tryConsumeExpectedToken(RootSignatureToken::Kind Expected); bool tryConsumeExpectedToken(ArrayRef Expected); + /// Consume tokens until the expected token has been peeked to be next + /// or we have reached the end of the stream. Note that this means the + /// expected token will be the next token not CurToken. + /// + /// Returns true if it found a token of the given type. + bool skipUntilExpectedToken(RootSignatureToken::Kind Expected); + bool skipUntilExpectedToken(ArrayRef Expected); + /// Convert the token's offset in the signature string to its SourceLocation /// /// This allows to currently retrieve the location for multi-token diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp index 87de627a98fb7..ceeb4c9fa8c0f 100644 --- a/clang/lib/Parse/ParseHLSLRootSignature.cpp +++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp @@ -17,6 +17,15 @@ namespace hlsl { using TokenKind = RootSignatureToken::Kind; +static const TokenKind RootElementKeywords[] = { +TokenKind::kw_RootFlags, +TokenKind::kw_CBV, +TokenKind::kw_UAV, +TokenKind::kw_SRV, +TokenKind::kw_DescriptorTable, +TokenKind::kw_StaticSampler, +}; + RootSignatureParser::RootSignatureParser( llvm::dxbc::RootSignatureVersion Version, SmallVector &Elements, StringLiteral *Signature, @@ -27,51 +36,68 @@ RootSignatureParser::RootSignatureParser( bool RootSignatureParser::parse() { // Iterate as many RootSignatureElements as possible, until we hit the // end of the stream + bool HadError = false; while (!peekExpectedToken(TokenKind::end_of_stream)) { +bool HadLocalError = false; if (tryConsumeExpectedToken(TokenKind::kw_RootFlags)) { SourceLocation ElementLoc = getTokenLocation(CurToken); auto Flags = parseRootFlags(); - if (!Flags.has_value()) -return true; - Elements.emplace_back(RootSignatureElement(ElementLoc, *Flags)); + if (Flags.has_value()) +Elements.emplace_back(RootSignatureElement(ElementLoc, *Flags)); + else +HadLocalError = true; } else if (tryConsumeExpectedToken(TokenKind::kw_RootConstants)) { SourceLocation ElementLoc = getTokenLocation(CurToken); auto Constants = parseRootConstants(); - if (!Constants.has_value()) -return true; - Elements.emplace_back(RootSignatureElement(ElementLoc, *Constants)); + if (Constants.has_value()) +Elements.emplace_back(RootSignatureElement(ElementLoc, *Constants)); + else +HadLocalError = true; } else if (tryConsumeExpectedToken(TokenKind::kw_DescriptorTable)) { SourceLocation ElementLoc = getTokenLocation(CurToken); auto Table = parseDescriptorTable(); - if (!Table.has_value()) -return true; - Elements.emplace_back(RootSignatureElement(ElementLoc, *Table)); + if (Table.has_value()) +Elements.emplace_back(RootSignatureElement(ElementLoc, *Table)); + else { +HadLocalError = true; +// We are within a DescriptorTable, we will do our best to recover +// by skipping until we encounter the expected closing ')'. +skipUntilExpectedToken(TokenKind::pu_r_paren); +consumeNextToken(); + } } else if (tryConsumeExpectedToken( {TokenKind::kw_CBV, TokenKind::kw_SRV, TokenKind::kw_UAV})) { SourceLocation ElementLoc = getTokenLocation(CurToken); auto Descriptor = parseRootDescriptor(); - if (!Descriptor.has_value()) -return true; - Elements.emplace_back(RootSignatureElement(ElementLoc, *Descriptor)); + if (Descriptor.has_value()) +Elements.emplace_back(RootSignatureElement(ElementLoc, *Descriptor)); + else +HadLocalError = true; } else if (tryConsumeExpectedToken(TokenKind::kw_StaticSampler)) { SourceLocation ElementLoc = getTokenLocation(CurToken); auto Sampler = parseStaticSampler(); - if (!Sampler.has_value()) -return true; - Elements.emplace_back(RootSignatureElement(ElementLoc, *Sampler
[llvm-branch-commits] [llvm] [IR2Vec] Add embeddings mode to llvm-ir2vec tool (PR #147844)
https://github.com/svkeerthy updated https://github.com/llvm/llvm-project/pull/147844 >From 6fd2dcac888426bc68570a6352e3f9c7b5fb358c Mon Sep 17 00:00:00 2001 From: svkeerthy Date: Wed, 9 Jul 2025 22:44:03 + Subject: [PATCH] IR2Vec Tool Enhancements --- llvm/test/lit.cfg.py | 7 + llvm/test/tools/llvm-ir2vec/embeddings.ll | 73 + llvm/test/tools/llvm-ir2vec/triplets.ll | 2 +- llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp| 182 -- 4 files changed, 252 insertions(+), 12 deletions(-) create mode 100644 llvm/test/tools/llvm-ir2vec/embeddings.ll diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py index 771d9245368b1..8a1b001695edc 100644 --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -93,6 +93,13 @@ def get_asan_rtlib(): config.substitutions.append(("%exeext", config.llvm_exe_ext)) config.substitutions.append(("%llvm_src_root", config.llvm_src_root)) +# Add IR2Vec test vocabulary path substitution +config.substitutions.append( +( +"%ir2vec_test_vocab_dir", +os.path.join(config.test_source_root, "Analysis", "IR2Vec", "Inputs"), +) +) lli_args = [] # The target triple used by default by lli is the process target triple (some diff --git a/llvm/test/tools/llvm-ir2vec/embeddings.ll b/llvm/test/tools/llvm-ir2vec/embeddings.ll new file mode 100644 index 0..993ea865170f9 --- /dev/null +++ b/llvm/test/tools/llvm-ir2vec/embeddings.ll @@ -0,0 +1,73 @@ +; RUN: llvm-ir2vec --mode=embeddings --ir2vec-vocab-path=%ir2vec_test_vocab_dir/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-DEFAULT +; RUN: llvm-ir2vec --mode=embeddings --level=func --ir2vec-vocab-path=%ir2vec_test_vocab_dir/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-FUNC-LEVEL +; RUN: llvm-ir2vec --mode=embeddings --level=func --function=abc --ir2vec-vocab-path=%ir2vec_test_vocab_dir/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-FUNC-LEVEL-ABC +; RUN: not llvm-ir2vec --mode=embeddings --level=func --function=def --ir2vec-vocab-path=%ir2vec_test_vocab_dir/dummy_3D_nonzero_opc_vocab.json %s 2>&1 | FileCheck %s -check-prefix=CHECK-FUNC-DEF +; RUN: llvm-ir2vec --mode=embeddings --level=bb --ir2vec-vocab-path=%ir2vec_test_vocab_dir/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-BB-LEVEL +; RUN: llvm-ir2vec --mode=embeddings --level=bb --function=abc_repeat --ir2vec-vocab-path=%ir2vec_test_vocab_dir/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-BB-LEVEL-ABC-REPEAT +; RUN: llvm-ir2vec --mode=embeddings --level=inst --function=abc_repeat --ir2vec-vocab-path=%ir2vec_test_vocab_dir/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-INST-LEVEL-ABC-REPEAT + +define dso_local noundef float @abc(i32 noundef %a, float noundef %b) #0 { +entry: + %a.addr = alloca i32, align 4 + %b.addr = alloca float, align 4 + store i32 %a, ptr %a.addr, align 4 + store float %b, ptr %b.addr, align 4 + %0 = load i32, ptr %a.addr, align 4 + %1 = load i32, ptr %a.addr, align 4 + %mul = mul nsw i32 %0, %1 + %conv = sitofp i32 %mul to float + %2 = load float, ptr %b.addr, align 4 + %add = fadd float %conv, %2 + ret float %add +} + +define dso_local noundef float @abc_repeat(i32 noundef %a, float noundef %b) #0 { +entry: + %a.addr = alloca i32, align 4 + %b.addr = alloca float, align 4 + store i32 %a, ptr %a.addr, align 4 + store float %b, ptr %b.addr, align 4 + %0 = load i32, ptr %a.addr, align 4 + %1 = load i32, ptr %a.addr, align 4 + %mul = mul nsw i32 %0, %1 + %conv = sitofp i32 %mul to float + %2 = load float, ptr %b.addr, align 4 + %add = fadd float %conv, %2 + ret float %add +} + +; CHECK-DEFAULT: Function: abc +; CHECK-DEFAULT-NEXT: [ 878.00 889.00 900.00 ] +; CHECK-DEFAULT-NEXT: Function: abc_repeat +; CHECK-DEFAULT-NEXT: [ 878.00 889.00 900.00 ] + +; CHECK-FUNC-LEVEL: Function: abc +; CHECK-FUNC-LEVEL-NEXT: [ 878.00 889.00 900.00 ] +; CHECK-FUNC-LEVEL-NEXT: Function: abc_repeat +; CHECK-FUNC-LEVEL-NEXT: [ 878.00 889.00 900.00 ] + +; CHECK-FUNC-LEVEL-ABC: Function: abc +; CHECK-FUNC-LEVEL-NEXT-ABC: [ 878.00 889.00 900.00 ] + +; CHECK-FUNC-DEF: Error: Function 'def' not found + +; CHECK-BB-LEVEL: Function: abc +; CHECK-BB-LEVEL-NEXT: entry: [ 878.00 889.00 900.00 ] +; CHECK-BB-LEVEL-NEXT: Function: abc_repeat +; CHECK-BB-LEVEL-NEXT: entry: [ 878.00 889.00 900.00 ] + +; CHECK-BB-LEVEL-ABC-REPEAT: Function: abc_repeat +; CHECK-BB-LEVEL-ABC-REPEAT-NEXT: entry: [ 878.00 889.00 900.00 ] + +; CHECK-INST-LEVEL-ABC-REPEAT: Function: abc_repeat +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %a.addr = alloca i32, align 4 [ 91.00 92.00 93.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %b.addr = alloca float, align 4 [ 91.00 92.00 93.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: store i32 %a, ptr %a.addr, align 4 [ 97.00 98.00 99.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: store float %b, ptr %b.addr, align
[llvm-branch-commits] [clang] [HLSL][RootSignature] Audit `RootSignatureParser` diagnostic production (PR #147800)
https://github.com/Icohedron edited https://github.com/llvm/llvm-project/pull/147800 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][RootSignature] Audit `RootSignatureParser` diagnostic production (PR #147800)
https://github.com/Icohedron approved this pull request. Seems fine to me. Could use a second approval to make sure https://github.com/llvm/llvm-project/pull/147800 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][RootSignature] Audit `RootSignatureParser` diagnostic production (PR #147800)
https://github.com/Icohedron edited https://github.com/llvm/llvm-project/pull/147800 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][RootSignature] Audit `RootSignatureParser` diagnostic production (PR #147800)
@@ -17,24 +17,89 @@ void bad_root_signature_2() {} [RootSignature(""), RootSignature("")] // expected-warning {{attribute 'RootSignature' is already applied}} void bad_root_signature_3() {} -[RootSignature("DescriptorTable(), invalid")] // expected-error {{expected end of stream to denote end of parameters, or, another valid parameter of RootSignature}} +// expected-error@+1 {{invalid parameter of RootSignature}} +[RootSignature("DescriptorTable(), invalid")] void bad_root_signature_4() {} -// expected-error@+1 {{expected ')' to denote end of parameters, or, another valid parameter of RootConstants}} -[RootSignature("RootConstants(b0, num32BitConstants = 1, invalid)")] +// expected-error@+1 {{expected ')' or ','}} Icohedron wrote: nit: Perhaps check for column number to see where a ')' or ',' is expected? https://github.com/llvm/llvm-project/pull/147800 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [HLSL][RootSignature] Allow for multiple parsing errors in `RootSignatureParser` (PR #147832)
https://github.com/joaosaffran approved this pull request. https://github.com/llvm/llvm-project/pull/147832 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] 9c48cb1 - Revert "[mlir][vector] Refactor WarpOpScfForOp to support unused or swapped f…"
Author: Charitha Saumya Date: 2025-07-11T13:19:18-07:00 New Revision: 9c48cb1fcd99423956f2dd376ddf6c44b80c343d URL: https://github.com/llvm/llvm-project/commit/9c48cb1fcd99423956f2dd376ddf6c44b80c343d DIFF: https://github.com/llvm/llvm-project/commit/9c48cb1fcd99423956f2dd376ddf6c44b80c343d.diff LOG: Revert "[mlir][vector] Refactor WarpOpScfForOp to support unused or swapped f…" This reverts commit 3092b765ba0b2d20bd716944dda86ea8e4ad12e3. Added: Modified: mlir/lib/Dialect/Vector/Transforms/VectorDistribute.cpp mlir/lib/Dialect/XeGPU/Transforms/XeGPUSubgroupDistribute.cpp mlir/test/Dialect/Vector/vector-warp-distribute.mlir Removed: diff --git a/mlir/lib/Dialect/Vector/Transforms/VectorDistribute.cpp b/mlir/lib/Dialect/Vector/Transforms/VectorDistribute.cpp index e62031412eab6..c8566b1ff83ef 100644 --- a/mlir/lib/Dialect/Vector/Transforms/VectorDistribute.cpp +++ b/mlir/lib/Dialect/Vector/Transforms/VectorDistribute.cpp @@ -1704,18 +1704,19 @@ struct WarpOpScfForOp : public WarpDistributionPattern { : WarpDistributionPattern(ctx, b), distributionMapFn(std::move(fn)) {} LogicalResult matchAndRewrite(WarpExecuteOnLane0Op warpOp, PatternRewriter &rewriter) const override { -auto warpOpYield = cast( +auto yield = cast( warpOp.getBodyRegion().getBlocks().begin()->getTerminator()); -// Only pick up `ForOp` if it is the last op in the region. -Operation *lastNode = warpOpYield->getPrevNode(); +// Only pick up forOp if it is the last op in the region. +Operation *lastNode = yield->getPrevNode(); auto forOp = dyn_cast_or_null(lastNode); if (!forOp) return failure(); -// Collect Values that come from the `WarpOp` but are outside the `ForOp`. -// Those Values need to be returned by the new warp op. +// Collect Values that come from the warp op but are outside the forOp. +// Those Value needs to be returned by the original warpOp and passed to +// the new op. llvm::SmallSetVector escapingValues; -SmallVector escapingValueInputTypes; -SmallVector escapingValueDistTypes; +SmallVector inputTypes; +SmallVector distTypes; mlir::visitUsedValuesDefinedAbove( forOp.getBodyRegion(), [&](OpOperand *operand) { Operation *parent = operand->get().getParentRegion()->getParentOp(); @@ -1727,153 +1728,81 @@ struct WarpOpScfForOp : public WarpDistributionPattern { AffineMap map = distributionMapFn(operand->get()); distType = getDistributedType(vecType, map, warpOp.getWarpSize()); } -escapingValueInputTypes.push_back(operand->get().getType()); -escapingValueDistTypes.push_back(distType); +inputTypes.push_back(operand->get().getType()); +distTypes.push_back(distType); } }); -if (llvm::is_contained(escapingValueDistTypes, Type{})) +if (llvm::is_contained(distTypes, Type{})) return failure(); -// `WarpOp` can yield two types of values: -// 1. Values that are not results of the `ForOp`: -//These values must also be yielded by the new `WarpOp`. Also, we need -//to record the index mapping for these values to replace them later. -// 2. Values that are results of the `ForOp`: -//In this case, we record the index mapping between the `WarpOp` result -//index and matching `ForOp` result index. -SmallVector nonForYieldedValues; -SmallVector nonForResultIndices; -llvm::SmallDenseMap forResultMapping; -for (OpOperand &yieldOperand : warpOpYield->getOpOperands()) { - // Yielded value is not a result of the forOp. - if (yieldOperand.get().getDefiningOp() != forOp.getOperation()) { -nonForYieldedValues.push_back(yieldOperand.get()); -nonForResultIndices.push_back(yieldOperand.getOperandNumber()); + +SmallVector newRetIndices; +WarpExecuteOnLane0Op newWarpOp = moveRegionToNewWarpOpAndAppendReturns( +rewriter, warpOp, escapingValues.getArrayRef(), distTypes, +newRetIndices); +yield = cast( +newWarpOp.getBodyRegion().getBlocks().begin()->getTerminator()); + +SmallVector newOperands; +SmallVector resultIdx; +// Collect all the outputs coming from the forOp. +for (OpOperand &yieldOperand : yield->getOpOperands()) { + if (yieldOperand.get().getDefiningOp() != forOp.getOperation()) continue; - } - OpResult forResult = cast(yieldOperand.get()); - forResultMapping[yieldOperand.getOperandNumber()] = - forResult.getResultNumber(); + auto forResult = cast(yieldOperand.get()); + newOperands.push_back( + newWarpOp.getResult(yieldOperand.getOperandNumber())); + yieldOperand.set(forOp.getInitArgs()[forResult.getResultNumber()]); + resultIdx.push_back(yieldOperand.g
[llvm-branch-commits] [clang] [HLSL][RootSignature] Audit `RootSignatureParser` diagnostic production (PR #147800)
https://github.com/joaosaffran approved this pull request. https://github.com/llvm/llvm-project/pull/147800 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [IR2Vec] Add embeddings mode to llvm-ir2vec tool (PR #147844)
https://github.com/svkeerthy updated https://github.com/llvm/llvm-project/pull/147844 >From bf757c03868bf5e85966440408e41f5343727384 Mon Sep 17 00:00:00 2001 From: svkeerthy Date: Wed, 9 Jul 2025 22:44:03 + Subject: [PATCH] IR2Vec Tool Enhancements --- llvm/test/tools/llvm-ir2vec/embeddings.ll | 73 + llvm/test/tools/llvm-ir2vec/triplets.ll | 2 +- llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp| 185 -- 3 files changed, 248 insertions(+), 12 deletions(-) create mode 100644 llvm/test/tools/llvm-ir2vec/embeddings.ll diff --git a/llvm/test/tools/llvm-ir2vec/embeddings.ll b/llvm/test/tools/llvm-ir2vec/embeddings.ll new file mode 100644 index 0..d5eed749193ac --- /dev/null +++ b/llvm/test/tools/llvm-ir2vec/embeddings.ll @@ -0,0 +1,73 @@ +; RUN: llvm-ir2vec --mode=embeddings --ir2vec-vocab-path=%S/../../Analysis/IR2Vec/Inputs/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-DEFAULT +; RUN: llvm-ir2vec --mode=embeddings --level=func --ir2vec-vocab-path=%S/../../Analysis/IR2Vec/Inputs/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-FUNC-LEVEL +; RUN: llvm-ir2vec --mode=embeddings --level=func --function=abc --ir2vec-vocab-path=%S/../../Analysis/IR2Vec/Inputs/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-FUNC-LEVEL-ABC +; RUN: not llvm-ir2vec --mode=embeddings --level=func --function=def --ir2vec-vocab-path=%S/../../Analysis/IR2Vec/Inputs/dummy_3D_nonzero_opc_vocab.json %s 2>&1 | FileCheck %s -check-prefix=CHECK-FUNC-DEF +; RUN: llvm-ir2vec --mode=embeddings --level=bb --ir2vec-vocab-path=%S/../../Analysis/IR2Vec/Inputs/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-BB-LEVEL +; RUN: llvm-ir2vec --mode=embeddings --level=bb --function=abc_repeat --ir2vec-vocab-path=%S/../../Analysis/IR2Vec/Inputs/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-BB-LEVEL-ABC-REPEAT +; RUN: llvm-ir2vec --mode=embeddings --level=inst --function=abc_repeat --ir2vec-vocab-path=%S/../../Analysis/IR2Vec/Inputs/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-INST-LEVEL-ABC-REPEAT + +define dso_local noundef float @abc(i32 noundef %a, float noundef %b) #0 { +entry: + %a.addr = alloca i32, align 4 + %b.addr = alloca float, align 4 + store i32 %a, ptr %a.addr, align 4 + store float %b, ptr %b.addr, align 4 + %0 = load i32, ptr %a.addr, align 4 + %1 = load i32, ptr %a.addr, align 4 + %mul = mul nsw i32 %0, %1 + %conv = sitofp i32 %mul to float + %2 = load float, ptr %b.addr, align 4 + %add = fadd float %conv, %2 + ret float %add +} + +define dso_local noundef float @abc_repeat(i32 noundef %a, float noundef %b) #0 { +entry: + %a.addr = alloca i32, align 4 + %b.addr = alloca float, align 4 + store i32 %a, ptr %a.addr, align 4 + store float %b, ptr %b.addr, align 4 + %0 = load i32, ptr %a.addr, align 4 + %1 = load i32, ptr %a.addr, align 4 + %mul = mul nsw i32 %0, %1 + %conv = sitofp i32 %mul to float + %2 = load float, ptr %b.addr, align 4 + %add = fadd float %conv, %2 + ret float %add +} + +; CHECK-DEFAULT: Function: abc +; CHECK-DEFAULT-NEXT: [ 878.00 889.00 900.00 ] +; CHECK-DEFAULT-NEXT: Function: abc_repeat +; CHECK-DEFAULT-NEXT: [ 878.00 889.00 900.00 ] + +; CHECK-FUNC-LEVEL: Function: abc +; CHECK-FUNC-LEVEL-NEXT: [ 878.00 889.00 900.00 ] +; CHECK-FUNC-LEVEL-NEXT: Function: abc_repeat +; CHECK-FUNC-LEVEL-NEXT: [ 878.00 889.00 900.00 ] + +; CHECK-FUNC-LEVEL-ABC: Function: abc +; CHECK-FUNC-LEVEL-NEXT-ABC: [ 878.00 889.00 900.00 ] + +; CHECK-FUNC-DEF: Error: Function 'def' not found + +; CHECK-BB-LEVEL: Function: abc +; CHECK-BB-LEVEL-NEXT: entry: [ 878.00 889.00 900.00 ] +; CHECK-BB-LEVEL-NEXT: Function: abc_repeat +; CHECK-BB-LEVEL-NEXT: entry: [ 878.00 889.00 900.00 ] + +; CHECK-BB-LEVEL-ABC-REPEAT: Function: abc_repeat +; CHECK-BB-LEVEL-ABC-REPEAT-NEXT: entry: [ 878.00 889.00 900.00 ] + +; CHECK-INST-LEVEL-ABC-REPEAT: Function: abc_repeat +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %a.addr = alloca i32, align 4 [ 91.00 92.00 93.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %b.addr = alloca float, align 4 [ 91.00 92.00 93.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: store i32 %a, ptr %a.addr, align 4 [ 97.00 98.00 99.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: store float %b, ptr %b.addr, align 4 [ 97.00 98.00 99.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %0 = load i32, ptr %a.addr, align 4 [ 94.00 95.00 96.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %1 = load i32, ptr %a.addr, align 4 [ 94.00 95.00 96.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %mul = mul nsw i32 %0, %1 [ 49.00 50.00 51.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %conv = sitofp i32 %mul to float [ 130.00 131.00 132.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %2 = load float, ptr %b.addr, align 4 [ 94.00 95.00 96.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %add = fadd float %conv, %2 [ 40.00 41.00 42.00 ] +; CHECK-INST-LEVEL-ABC-R
[llvm-branch-commits] [llvm] [IR2Vec] Add embeddings mode to llvm-ir2vec tool (PR #147844)
https://github.com/svkeerthy updated https://github.com/llvm/llvm-project/pull/147844 >From bf757c03868bf5e85966440408e41f5343727384 Mon Sep 17 00:00:00 2001 From: svkeerthy Date: Wed, 9 Jul 2025 22:44:03 + Subject: [PATCH] IR2Vec Tool Enhancements --- llvm/test/tools/llvm-ir2vec/embeddings.ll | 73 + llvm/test/tools/llvm-ir2vec/triplets.ll | 2 +- llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp| 185 -- 3 files changed, 248 insertions(+), 12 deletions(-) create mode 100644 llvm/test/tools/llvm-ir2vec/embeddings.ll diff --git a/llvm/test/tools/llvm-ir2vec/embeddings.ll b/llvm/test/tools/llvm-ir2vec/embeddings.ll new file mode 100644 index 0..d5eed749193ac --- /dev/null +++ b/llvm/test/tools/llvm-ir2vec/embeddings.ll @@ -0,0 +1,73 @@ +; RUN: llvm-ir2vec --mode=embeddings --ir2vec-vocab-path=%S/../../Analysis/IR2Vec/Inputs/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-DEFAULT +; RUN: llvm-ir2vec --mode=embeddings --level=func --ir2vec-vocab-path=%S/../../Analysis/IR2Vec/Inputs/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-FUNC-LEVEL +; RUN: llvm-ir2vec --mode=embeddings --level=func --function=abc --ir2vec-vocab-path=%S/../../Analysis/IR2Vec/Inputs/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-FUNC-LEVEL-ABC +; RUN: not llvm-ir2vec --mode=embeddings --level=func --function=def --ir2vec-vocab-path=%S/../../Analysis/IR2Vec/Inputs/dummy_3D_nonzero_opc_vocab.json %s 2>&1 | FileCheck %s -check-prefix=CHECK-FUNC-DEF +; RUN: llvm-ir2vec --mode=embeddings --level=bb --ir2vec-vocab-path=%S/../../Analysis/IR2Vec/Inputs/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-BB-LEVEL +; RUN: llvm-ir2vec --mode=embeddings --level=bb --function=abc_repeat --ir2vec-vocab-path=%S/../../Analysis/IR2Vec/Inputs/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-BB-LEVEL-ABC-REPEAT +; RUN: llvm-ir2vec --mode=embeddings --level=inst --function=abc_repeat --ir2vec-vocab-path=%S/../../Analysis/IR2Vec/Inputs/dummy_3D_nonzero_opc_vocab.json %s | FileCheck %s -check-prefix=CHECK-INST-LEVEL-ABC-REPEAT + +define dso_local noundef float @abc(i32 noundef %a, float noundef %b) #0 { +entry: + %a.addr = alloca i32, align 4 + %b.addr = alloca float, align 4 + store i32 %a, ptr %a.addr, align 4 + store float %b, ptr %b.addr, align 4 + %0 = load i32, ptr %a.addr, align 4 + %1 = load i32, ptr %a.addr, align 4 + %mul = mul nsw i32 %0, %1 + %conv = sitofp i32 %mul to float + %2 = load float, ptr %b.addr, align 4 + %add = fadd float %conv, %2 + ret float %add +} + +define dso_local noundef float @abc_repeat(i32 noundef %a, float noundef %b) #0 { +entry: + %a.addr = alloca i32, align 4 + %b.addr = alloca float, align 4 + store i32 %a, ptr %a.addr, align 4 + store float %b, ptr %b.addr, align 4 + %0 = load i32, ptr %a.addr, align 4 + %1 = load i32, ptr %a.addr, align 4 + %mul = mul nsw i32 %0, %1 + %conv = sitofp i32 %mul to float + %2 = load float, ptr %b.addr, align 4 + %add = fadd float %conv, %2 + ret float %add +} + +; CHECK-DEFAULT: Function: abc +; CHECK-DEFAULT-NEXT: [ 878.00 889.00 900.00 ] +; CHECK-DEFAULT-NEXT: Function: abc_repeat +; CHECK-DEFAULT-NEXT: [ 878.00 889.00 900.00 ] + +; CHECK-FUNC-LEVEL: Function: abc +; CHECK-FUNC-LEVEL-NEXT: [ 878.00 889.00 900.00 ] +; CHECK-FUNC-LEVEL-NEXT: Function: abc_repeat +; CHECK-FUNC-LEVEL-NEXT: [ 878.00 889.00 900.00 ] + +; CHECK-FUNC-LEVEL-ABC: Function: abc +; CHECK-FUNC-LEVEL-NEXT-ABC: [ 878.00 889.00 900.00 ] + +; CHECK-FUNC-DEF: Error: Function 'def' not found + +; CHECK-BB-LEVEL: Function: abc +; CHECK-BB-LEVEL-NEXT: entry: [ 878.00 889.00 900.00 ] +; CHECK-BB-LEVEL-NEXT: Function: abc_repeat +; CHECK-BB-LEVEL-NEXT: entry: [ 878.00 889.00 900.00 ] + +; CHECK-BB-LEVEL-ABC-REPEAT: Function: abc_repeat +; CHECK-BB-LEVEL-ABC-REPEAT-NEXT: entry: [ 878.00 889.00 900.00 ] + +; CHECK-INST-LEVEL-ABC-REPEAT: Function: abc_repeat +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %a.addr = alloca i32, align 4 [ 91.00 92.00 93.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %b.addr = alloca float, align 4 [ 91.00 92.00 93.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: store i32 %a, ptr %a.addr, align 4 [ 97.00 98.00 99.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: store float %b, ptr %b.addr, align 4 [ 97.00 98.00 99.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %0 = load i32, ptr %a.addr, align 4 [ 94.00 95.00 96.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %1 = load i32, ptr %a.addr, align 4 [ 94.00 95.00 96.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %mul = mul nsw i32 %0, %1 [ 49.00 50.00 51.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %conv = sitofp i32 %mul to float [ 130.00 131.00 132.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %2 = load float, ptr %b.addr, align 4 [ 94.00 95.00 96.00 ] +; CHECK-INST-LEVEL-ABC-REPEAT-NEXT: %add = fadd float %conv, %2 [ 40.00 41.00 42.00 ] +; CHECK-INST-LEVEL-ABC-R
[llvm-branch-commits] [llvm] [IR2Vec] Add llvm-ir2vec tool for generating triplet embeddings (PR #147842)
https://github.com/svkeerthy updated https://github.com/llvm/llvm-project/pull/147842 >From 5f1f3fe9f7e07bb44802d3026fdf8ac3abf89ba2 Mon Sep 17 00:00:00 2001 From: svkeerthy Date: Wed, 9 Jul 2025 22:39:39 + Subject: [PATCH] IR2Vec Tool --- llvm/test/CMakeLists.txt| 1 + llvm/test/lit.cfg.py| 1 + llvm/test/tools/llvm-ir2vec/triplets.ll | 38 ++ llvm/tools/llvm-ir2vec/CMakeLists.txt | 10 ++ llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp | 150 5 files changed, 200 insertions(+) create mode 100644 llvm/test/tools/llvm-ir2vec/triplets.ll create mode 100644 llvm/tools/llvm-ir2vec/CMakeLists.txt create mode 100644 llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt index 2a6135da9a61e..3426b6ff8d24d 100644 --- a/llvm/test/CMakeLists.txt +++ b/llvm/test/CMakeLists.txt @@ -97,6 +97,7 @@ set(LLVM_TEST_DEPENDS llvm-exegesis llvm-extract llvm-gsymutil + llvm-ir2vec llvm-isel-fuzzer llvm-ifs llvm-install-name-tool diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py index bd6e37c848d8c..771d9245368b1 100644 --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -197,6 +197,7 @@ def get_asan_rtlib(): "llvm-dlltool", "llvm-exegesis", "llvm-extract", +"llvm-ir2vec", "llvm-isel-fuzzer", "llvm-ifs", "llvm-install-name-tool", diff --git a/llvm/test/tools/llvm-ir2vec/triplets.ll b/llvm/test/tools/llvm-ir2vec/triplets.ll new file mode 100644 index 0..fa5aaa895406f --- /dev/null +++ b/llvm/test/tools/llvm-ir2vec/triplets.ll @@ -0,0 +1,38 @@ +; RUN: llvm-ir2vec %s | FileCheck %s -check-prefix=TRIPLETS + +define i32 @simple_add(i32 %a, i32 %b) { +entry: + %add = add i32 %a, %b + ret i32 %add +} + +define i32 @simple_mul(i32 %x, i32 %y) { +entry: + %mul = mul i32 %x, %y + ret i32 %mul +} + +define i32 @test_function(i32 %arg1, i32 %arg2) { +entry: + %local1 = alloca i32, align 4 + %local2 = alloca i32, align 4 + store i32 %arg1, ptr %local1, align 4 + store i32 %arg2, ptr %local2, align 4 + %load1 = load i32, ptr %local1, align 4 + %load2 = load i32, ptr %local2, align 4 + %result = add i32 %load1, %load2 + ret i32 %result +} + +; TRIPLETS: Add IntegerTy Variable Variable +; TRIPLETS-NEXT: Ret VoidTy Variable +; TRIPLETS-NEXT: Mul IntegerTy Variable Variable +; TRIPLETS-NEXT: Ret VoidTy Variable +; TRIPLETS-NEXT: Alloca PointerTy Constant +; TRIPLETS-NEXT: Alloca PointerTy Constant +; TRIPLETS-NEXT: Store VoidTy Variable Pointer +; TRIPLETS-NEXT: Store VoidTy Variable Pointer +; TRIPLETS-NEXT: Load IntegerTy Pointer +; TRIPLETS-NEXT: Load IntegerTy Pointer +; TRIPLETS-NEXT: Add IntegerTy Variable Variable +; TRIPLETS-NEXT: Ret VoidTy Variable diff --git a/llvm/tools/llvm-ir2vec/CMakeLists.txt b/llvm/tools/llvm-ir2vec/CMakeLists.txt new file mode 100644 index 0..a4cf9690e86b5 --- /dev/null +++ b/llvm/tools/llvm-ir2vec/CMakeLists.txt @@ -0,0 +1,10 @@ +set(LLVM_LINK_COMPONENTS + Analysis + Core + IRReader + Support + ) + +add_llvm_tool(llvm-ir2vec + llvm-ir2vec.cpp + ) diff --git a/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp b/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp new file mode 100644 index 0..35e1c995fa4cc --- /dev/null +++ b/llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp @@ -0,0 +1,150 @@ +//===- llvm-ir2vec.cpp - IR2Vec Embedding Generation Tool -===// +// +// 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 +// +//===--===// +/// +/// \file +/// This file implements the IR2Vec embedding generation tool. +/// +/// Currently supports triplet generation for vocabulary training. +/// Future updates will support embedding generation using trained vocabulary. +/// +/// Usage: llvm-ir2vec input.bc -o triplets.txt +/// +/// TODO: Add embedding generation mode with vocabulary support +/// +//===--===// + +#include "llvm/Analysis/IR2Vec.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Errc.h" +#include "llvm/Support/InitLLVM.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; +using namespace ir2vec; + +#define DEBUG_TYPE "ir2vec" + +static cl::OptionCategory IR2VecToolCategory("IR2Vec Tool Options"); + +static cl::opt InputFilename(cl::Positional, + cl::desc("
[llvm-branch-commits] [llvm] [DirectX] Improve error accumulation in root signature parsing (PR #144465)
llvm-beanz wrote: Looking at this PR and https://github.com/llvm/llvm-project/pull/144577 led me to look a bit more at the code around this. I think the way you're handling errors in this code is a bit sub-optimal. Instead of having a bunch of report functions and chains of functions returning `bool`, you could instead have the functions return `llvm::Error` and use `joinErrors` to build up chains of errors which you can then choose to report at a higher level in the API. The LLVM Programmers Manual has a good section about `llvm::Error`: https://llvm.org/docs/ProgrammersManual.html#id23 https://github.com/llvm/llvm-project/pull/144465 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Improve error handling and validation in root signature parsing (PR #144577)
https://github.com/Icohedron dismissed https://github.com/llvm/llvm-project/pull/144577 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Improve error handling and validation in root signature parsing (PR #144577)
@@ -48,6 +48,71 @@ static bool reportValueError(LLVMContext *Ctx, Twine ParamName, return true; } +// Template function to get formatted type string based on C++ type +template std::string getTypeFormatted() { + if constexpr (std::is_same_v) { +return "string"; + } else if constexpr (std::is_same_v || + std::is_same_v) { +return "metadata"; + } else if constexpr (std::is_same_v || + std::is_same_v) { +return "constant"; + } else if constexpr (std::is_same_v) { +return "constant"; + } else if constexpr (std::is_same_v || + std::is_same_v) { +return "constant int"; + } else if constexpr (std::is_same_v) { +return "constant int"; + } + return "unknown"; +} + +// Helper function to get the actual type of a metadata operand +std::string getActualMDType(const MDNode *Node, unsigned Index) { + if (!Node || Index >= Node->getNumOperands()) +return "null"; + + Metadata *Op = Node->getOperand(Index); + if (!Op) +return "null"; + + if (isa(Op)) +return getTypeFormatted(); + + if (isa(Op)) { +if (auto *CAM = dyn_cast(Op)) { + Type *T = CAM->getValue()->getType(); + if (T->isIntegerTy()) +return (Twine("i") + Twine(T->getIntegerBitWidth())).str(); + if (T->isFloatingPointTy()) +return T->isFloatTy()? getTypeFormatted() + : T->isDoubleTy() ? getTypeFormatted() + : "fp"; + + return getTypeFormatted(); +} + } + if (isa(Op)) +return getTypeFormatted(); + + return "unknown"; +} + +// Helper function to simplify error reporting for invalid metadata values +template +auto reportInvalidTypeError(LLVMContext *Ctx, Twine ParamName, llvm-beanz wrote: `auto` as a return type rarely meets LLVM's coding standards: see: https://llvm.org/docs/CodingStandards.html#use-auto-type-deduction-to-make-code-more-readable https://github.com/llvm/llvm-project/pull/144577 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Improve error handling and validation in root signature parsing (PR #144577)
@@ -48,6 +48,71 @@ static bool reportValueError(LLVMContext *Ctx, Twine ParamName, return true; } +// Template function to get formatted type string based on C++ type +template std::string getTypeFormatted() { + if constexpr (std::is_same_v) { +return "string"; + } else if constexpr (std::is_same_v || + std::is_same_v) { +return "metadata"; + } else if constexpr (std::is_same_v || + std::is_same_v) { +return "constant"; + } else if constexpr (std::is_same_v) { +return "constant"; + } else if constexpr (std::is_same_v || + std::is_same_v) { +return "constant int"; + } else if constexpr (std::is_same_v) { +return "constant int"; + } + return "unknown"; +} + +// Helper function to get the actual type of a metadata operand +std::string getActualMDType(const MDNode *Node, unsigned Index) { llvm-beanz wrote: ```suggestion StringRef getActualMDType(const MDNode *Node, unsigned Index) { ``` https://github.com/llvm/llvm-project/pull/144577 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Improve error handling and validation in root signature parsing (PR #144577)
@@ -48,6 +48,71 @@ static bool reportValueError(LLVMContext *Ctx, Twine ParamName, return true; } +// Template function to get formatted type string based on C++ type +template std::string getTypeFormatted() { llvm-beanz wrote: Looks like this could be a StringRef. ```suggestion template StringRef getTypeFormatted() { ``` https://github.com/llvm/llvm-project/pull/144577 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DirectX] Improve error accumulation in root signature parsing (PR #144465)
@@ -699,19 +736,20 @@ static bool verifyBorderColor(uint32_t BorderColor) { static bool verifyLOD(float LOD) { return !std::isnan(LOD); } static bool validate(LLVMContext *Ctx, const mcdxbc::RootSignatureDesc &RSD) { - + bool HasError = false; if (!verifyVersion(RSD.Version)) { -return reportValueError(Ctx, "Version", RSD.Version); +HasError = reportValueError(Ctx, "Version", RSD.Version) || HasError; llvm-beanz wrote: This pattern seems really awkward because the report functions always return `true`. That means that the `||` is always unnecessary, but also the assignment itself isn't really as clear to understand as it could be. You could instead write this code as something like: ``` if (!verifyVersion(RSD.Version)) { reportValueError(...); HasError = true; } ``` This is more verbose but a lot easier to see what is happening. https://github.com/llvm/llvm-project/pull/144465 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DA] Add check for base pointer invariance (PR #148241)
https://github.com/kasuga-fj ready_for_review https://github.com/llvm/llvm-project/pull/148241 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DA] Add check for base pointer invariance (PR #148241)
@@ -113,7 +113,7 @@ define void @banerjee1(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp { ; CHECK-NEXT: Src: %2 = load i64, ptr %arrayidx6, align 8 --> Dst: store i64 %2, ptr %B.addr.12, align 8 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store i64 %2, ptr %B.addr.12, align 8 --> Dst: store i64 %2, ptr %B.addr.12, align 8 -; CHECK-NEXT:da analyze - output [* *]! kasuga-fj wrote: All the test changes except for FlipFlopBaseAddress.ll are related to dependencies between memory accesses of the form `*B++`. https://github.com/llvm/llvm-project/pull/148241 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DA] Add check for base pointer invariance (PR #148241)
https://github.com/kasuga-fj updated https://github.com/llvm/llvm-project/pull/148241 >From d914ea5f3c44387570cab65ce9a507ebf429f827 Mon Sep 17 00:00:00 2001 From: Ryotaro Kasuga Date: Fri, 11 Jul 2025 13:10:44 + Subject: [PATCH 1/3] [DA] Add check for base pointer invariance --- llvm/lib/Analysis/DependenceAnalysis.cpp | 16 .../DependenceAnalysis/FlipFlopBaseAddress.ll | 18 +- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp index 428342f51ad2e..07bf560772c8c 100644 --- a/llvm/lib/Analysis/DependenceAnalysis.cpp +++ b/llvm/lib/Analysis/DependenceAnalysis.cpp @@ -3383,6 +3383,10 @@ bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst, SrcSubscripts, DstSubscripts)) return false; + assert(isLoopInvariant(SrcBase, SrcLoop) && + isLoopInvariant(DstBase, DstLoop) && + "Expected SrcBase and DstBase to be loop invariant"); + int Size = SrcSubscripts.size(); LLVM_DEBUG({ dbgs() << "\nSrcSubscripts: "; @@ -3666,6 +3670,18 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst, SCEVUnionPredicate(Assume, *SE)); } + // Even if the base pointers are the same, they may not be loop-invariant. It + // could lead to incorrect results, as we're analyzing loop-carried + // dependencies. + Loop *SrcLoop = LI->getLoopFor(Src->getParent()); + Loop *DstLoop = LI->getLoopFor(Dst->getParent()); + if (!isLoopInvariant(SrcBase, SrcLoop) || + !isLoopInvariant(DstBase, DstLoop)) { +LLVM_DEBUG(dbgs() << "The base pointer is not loop invariant.\n"); +return std::make_unique(Src, Dst, +SCEVUnionPredicate(Assume, *SE)); + } + uint64_t EltSize = SrcLoc.Size.toRaw(); const SCEV *SrcEv = SE->getMinusSCEV(SrcSCEV, SrcBase); const SCEV *DstEv = SE->getMinusSCEV(DstSCEV, DstBase); diff --git a/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll b/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll index 3e3426afab0f7..52cab0f77e73e 100644 --- a/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll +++ b/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll @@ -8,11 +8,11 @@ define float @bug41488_test1(float %f) { ; CHECK-LABEL: 'bug41488_test1' ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float %f, ptr %q, align 4 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store float %f, ptr %q, align 4 --> Dst: store float %f, ptr %q, align 4 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %g = alloca float, align 4 @@ -34,11 +34,11 @@ for.cond.cleanup: define void @bug41488_test2(i32 %n) { ; CHECK-LABEL: 'bug41488_test2' ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float 0.00e+00, ptr %q, align 4 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store float 0.00e+00, ptr %q, align 4 --> Dst: store float 0.00e+00, ptr %q, align 4 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %g = alloca float, align 4 @@ -68,7 +68,7 @@ define void @bug53942_foo(i32 noundef %n, ptr noalias nocapture noundef writeonl ; CHECK-NEXT: Src: %.pre = load double, ptr %B, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store double %.pre, ptr %arrayidx2, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %cmp8 = icmp sgt i32 %n, 1 @@ -99,11 +99,11 @@ for.body: ; preds = %for.body.preheader, define void @bug53942_bar(i32 noundef %n, ptr noalias noundef %A, ptr noalias noundef %B) { ; CHECK-LABEL: 'bug53942_bar' ; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: %0 = load double, ptr %arrayidx, align 8 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store double %0, ptr %arrayidx8, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: br label %for.cond @@ -173,7 +173,7 @@ for.end:
[llvm-branch-commits] [llvm] [SimplifyLibCalls] Add initial support for non-8-bit bytes (PR #106542)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106542 >From a7b7545c2e895b46a5aaa7525ad030ea0c48c163 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Wed, 28 Aug 2024 16:09:44 +0300 Subject: [PATCH] [SimplifyLibCalls] Add initial support for non-8-bit bytes The patch makes CharWidth argument of `getStringLength` mandatory and ensures the correct values are passed in most cases. This is *not* a complete support for unusual byte widths in SimplifyLibCalls since `getConstantStringInfo` returns false for those. The code guarded by `getConstantStringInfo` returning true is unchanged because the changes are currently not testable. --- llvm/include/llvm/Analysis/ValueTracking.h| 4 +- .../llvm/Transforms/Utils/SimplifyLibCalls.h | 4 +- llvm/lib/Analysis/MemoryBuiltins.cpp | 3 +- llvm/lib/Analysis/ValueTracking.cpp | 40 ++-- .../InstCombine/InstCombineCalls.cpp | 12 +- .../InstCombine/InstructionCombining.cpp | 5 +- .../lib/Transforms/Utils/SimplifyLibCalls.cpp | 191 -- .../InstCombine/SimplifyLibCalls/fputs-b16.ll | 19 ++ .../SimplifyLibCalls/fwrite-b16.ll| 19 ++ .../SimplifyLibCalls/memchr-b16.ll| 34 .../SimplifyLibCalls/memcmp-b32.ll| 32 +++ .../SimplifyLibCalls/memcpy-b16.ll| 69 +++ .../SimplifyLibCalls/memcpy_chk-b16.ll| 17 ++ .../SimplifyLibCalls/mempcpy-b16.ll | 17 ++ .../SimplifyLibCalls/memrchr-b16.ll | 20 ++ .../SimplifyLibCalls/memset-b16.ll| 66 ++ .../SimplifyLibCalls/stpcpy-b16.ll| 31 +++ .../SimplifyLibCalls/stpcpy_chk-b16.ll| 44 .../SimplifyLibCalls/stpncpy-b16.ll | 47 + .../SimplifyLibCalls/strcat-b16.ll| 20 ++ .../SimplifyLibCalls/strchr-b16.ll| 45 + .../SimplifyLibCalls/strcmp-b32.ll| 50 + .../SimplifyLibCalls/strcpy-b16.ll| 18 ++ .../SimplifyLibCalls/strcpy_chk-b16.ll| 30 +++ .../SimplifyLibCalls/strlcpy-b16.ll | 18 ++ .../SimplifyLibCalls/strlen-b16.ll| 16 ++ .../SimplifyLibCalls/strncat-b16.ll | 20 ++ .../SimplifyLibCalls/strncmp-b32.ll | 34 .../SimplifyLibCalls/strncpy-b16.ll | 43 .../SimplifyLibCalls/strndup-b16.ll | 17 ++ .../SimplifyLibCalls/strnlen-b16.ll | 18 ++ .../SimplifyLibCalls/wcslen-b16.ll| 19 ++ llvm/test/Transforms/InstCombine/bcmp-1.ll| 2 +- llvm/test/Transforms/InstCombine/memcmp-1.ll | 2 +- llvm/test/Transforms/InstCombine/strncmp-1.ll | 2 +- 35 files changed, 928 insertions(+), 100 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/fputs-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/fwrite-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memchr-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memcmp-b32.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memcpy_chk-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/mempcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memrchr-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memset-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/stpcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/stpcpy_chk-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/stpncpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcat-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strchr-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcmp-b32.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcpy_chk-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strlcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strlen-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strncat-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strncmp-b32.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strncpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strndup-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strnlen-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/wcslen-b16.ll diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h index
[llvm-branch-commits] [clang] [llvm] [ValueTracking] Add CharWidth argument to getConstantStringInfo (NFC) (PR #106541)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106541 >From 1591f0bc03f6e8437fad91870fddae87cf270ffd Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Wed, 28 Aug 2024 23:51:13 +0300 Subject: [PATCH] [ValueTracking] Add CharWidth argument to getConstantStringInfo (NFC) The method assumes that host chars and target chars have the same width. Add a CharWidth argument so that it can bail out if the requested char width differs from the host char width. Alternatively, the check could be done at call sites, but this is more error-prone. In the future, this method will be replaced with a different one that allows host/target chars to have different widths. The prototype will be the same except that StringRef is replaced with something that is byte width agnostic. Adding CharWidth argument now reduces the future diff. --- clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp | 4 +- llvm/include/llvm/Analysis/ValueTracking.h| 2 +- llvm/lib/Analysis/ValueTracking.cpp | 7 +- .../AMDGPU/AMDGPUPrintfRuntimeBinding.cpp | 4 +- llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp | 2 +- .../Target/SPIRV/SPIRVPrepareFunctions.cpp| 2 +- .../WebAssembly/WebAssemblyAsmPrinter.cpp | 2 +- .../AggressiveInstCombine.cpp | 12 +- .../lib/Transforms/Utils/AMDGPUEmitPrintf.cpp | 4 +- .../lib/Transforms/Utils/SimplifyLibCalls.cpp | 103 -- 10 files changed, 96 insertions(+), 46 deletions(-) diff --git a/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp b/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp index f09b3b92c4ea0..b7b65634238c4 100644 --- a/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp @@ -226,7 +226,7 @@ void CodeGenFunction::ProcessOrderScopeAMDGCN(Value *Order, Value *Scope, // Some of the atomic builtins take the scope as a string name. StringRef scp; - if (llvm::getConstantStringInfo(Scope, scp)) { + if (llvm::getConstantStringInfo(Scope, scp, /*CharWidth=*/8)) { SSID = getLLVMContext().getOrInsertSyncScopeID(scp); return; } @@ -281,7 +281,7 @@ void CodeGenFunction::AddAMDGPUFenceAddressSpaceMMRA(llvm::Instruction *Inst, for (unsigned K = 2; K < E->getNumArgs(); ++K) { llvm::Value *V = EmitScalarExpr(E->getArg(K)); StringRef AS; -if (llvm::getConstantStringInfo(V, AS)) { +if (llvm::getConstantStringInfo(V, AS, /*CharWidth=*/8)) { MMRAs.push_back({Tag, AS}); // TODO: Delete the resulting unused constant? continue; diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h index 02990a3cb44f7..e6fb3cb9bd044 100644 --- a/llvm/include/llvm/Analysis/ValueTracking.h +++ b/llvm/include/llvm/Analysis/ValueTracking.h @@ -404,7 +404,7 @@ LLVM_ABI bool getConstantDataArrayInfo(const Value *V, /// trailing null characters as well as any other characters that come after /// it. LLVM_ABI bool getConstantStringInfo(const Value *V, StringRef &Str, -bool TrimAtNul = true); +unsigned CharWidth, bool TrimAtNul = true); /// If we can compute the length of the string pointed to by the specified /// pointer, return 'len+1'. If we can't, return 0. diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 858d79b7f095b..ed202b8a1f6e5 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -6457,9 +6457,12 @@ bool llvm::getConstantDataArrayInfo(const Value *V, /// return true. When TrimAtNul is set, Str will contain only the bytes up /// to but not including the first nul. Return false on failure. bool llvm::getConstantStringInfo(const Value *V, StringRef &Str, - bool TrimAtNul) { + unsigned CharWidth, bool TrimAtNul) { + if (CharWidth != CHAR_BIT) +return false; + ConstantDataArraySlice Slice; - if (!getConstantDataArrayInfo(V, Slice, 8)) + if (!getConstantDataArrayInfo(V, Slice, CharWidth)) return false; if (Slice.Array == nullptr) { diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp index 7a2a7fc250e27..471dfbc53274c 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp @@ -121,7 +121,7 @@ static_assert(NonLiteralStr.size() == 3); static StringRef getAsConstantStr(Value *V) { StringRef S; - if (!getConstantStringInfo(V, S)) + if (!getConstantStringInfo(V, S, /*CharWidth=*/8)) S = NonLiteralStr; return S; @@ -154,7 +154,7 @@ bool AMDGPUPrintfRuntimeBindingImpl::lowerPrintfForGpu(Module &M) { Value *Op = CI->getArgOperand(0); StringRef FormatStr; -if (!getConstantStringInfo(Op, FormatStr)) { +if (!getConstantStringInfo(Op, FormatStr, /*CharWidth=*/8)) { V
[llvm-branch-commits] [llvm] [IRBuilder] Add getByteTy and use it in CreatePtrAdd (PR #106539)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106539 >From caa10b7614c372aea15ad17a23ec6e0a6b29f6a7 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Thu, 22 Aug 2024 15:10:58 +0300 Subject: [PATCH] [IRBuilder] Add getByteTy and use it in CreatePtrAdd The change requires DataLayout instance to be available, which, in turn, requires insertion point to be set. In-tree tests detected only one case when the function was called without setting an insertion point, it was changed to create a constant expression directly. --- llvm/include/llvm/IR/IRBuilder.h | 10 +++-- .../Instrumentation/SanitizerCoverage.cpp | 5 ++--- llvm/unittests/IR/IRBuilderTest.cpp | 22 +++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index 7c600e762a451..b0c60056e740d 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -543,6 +543,12 @@ class IRBuilderBase { // Type creation methods //======// + /// Fetch the type representing a byte. + IntegerType *getByteTy() { +const DataLayout &DL = BB->getDataLayout(); +return Type::getIntNTy(Context, DL.getByteWidth()); + } + /// Fetch the type representing a single bit IntegerType *getInt1Ty() { return Type::getInt1Ty(Context); @@ -2040,12 +2046,12 @@ class IRBuilderBase { Value *CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name = "", GEPNoWrapFlags NW = GEPNoWrapFlags::none()) { -return CreateGEP(getInt8Ty(), Ptr, Offset, Name, NW); +return CreateGEP(getByteTy(), Ptr, Offset, Name, NW); } Value *CreateInBoundsPtrAdd(Value *Ptr, Value *Offset, const Twine &Name = "") { -return CreateGEP(getInt8Ty(), Ptr, Offset, Name, +return CreateGEP(getByteTy(), Ptr, Offset, Name, GEPNoWrapFlags::inBounds()); } diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index 5b8ea1547ca2f..a45b56696f612 100644 --- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -357,14 +357,13 @@ ModuleSanitizerCoverage::CreateSecStartEnd(Module &M, const char *Section, GlobalVariable *SecEnd = new GlobalVariable(M, Ty, false, Linkage, nullptr, getSectionEnd(Section)); SecEnd->setVisibility(GlobalValue::HiddenVisibility); - IRBuilder<> IRB(M.getContext()); if (!TargetTriple.isOSBinFormatCOFF()) return std::make_pair(SecStart, SecEnd); // Account for the fact that on windows-msvc __start_* symbols actually // point to a uint64_t before the start of the array. - auto GEP = - IRB.CreatePtrAdd(SecStart, ConstantInt::get(IntptrTy, sizeof(uint64_t))); + Constant *GEP = ConstantExpr::getGetElementPtr( + Int8Ty, SecStart, ConstantInt::get(IntptrTy, sizeof(uint64_t))); return std::make_pair(GEP, SecEnd); } diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp index 4f2ede3321080..9a0be982b2175 100644 --- a/llvm/unittests/IR/IRBuilderTest.cpp +++ b/llvm/unittests/IR/IRBuilderTest.cpp @@ -525,6 +525,14 @@ TEST_F(IRBuilderTest, DataLayout) { EXPECT_FALSE(M->getDataLayout().isLegalInteger(32)); } +TEST_F(IRBuilderTest, GetByteTy) { + IRBuilder<> Builder(BB); + + EXPECT_TRUE(Builder.getByteTy()->isIntegerTy(8)); + M->setDataLayout("b:32"); + EXPECT_TRUE(Builder.getByteTy()->isIntegerTy(32)); +} + TEST_F(IRBuilderTest, GetIntTy) { IRBuilder<> Builder(BB); IntegerType *Ty1 = Builder.getInt1Ty(); @@ -536,6 +544,20 @@ TEST_F(IRBuilderTest, GetIntTy) { EXPECT_EQ(IntPtrTy, IntegerType::get(Ctx, IntPtrBitSize)); } +TEST_F(IRBuilderTest, CreatePtrAdd) { + IRBuilder<> Builder(BB); + + M->setDataLayout("b:16-p:32:32"); + Value *V = Builder.CreatePtrAdd(GV, ConstantInt::get(Ctx, APInt(32, 42))); + ASSERT_TRUE(isa(V)); + EXPECT_TRUE(cast(V)->getResultElementType()->isIntegerTy(16)); + + M->setDataLayout("b:32-p:64:32"); + V = Builder.CreateInBoundsPtrAdd(GV, ConstantInt::get(Ctx, APInt(64, 42))); + ASSERT_TRUE(isa(V)); + EXPECT_TRUE(cast(V)->getResultElementType()->isIntegerTy(32)); +} + TEST_F(IRBuilderTest, UnaryOperators) { IRBuilder Builder(BB); Value *V = Builder.CreateLoad(GV->getValueType(), GV); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [IR] Account for byte width in m_PtrAdd (PR #106540)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106540 >From 4d50f231545a49befa155dd68cb1e55cf8d7af33 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Thu, 29 Aug 2024 00:54:20 +0300 Subject: [PATCH] [IR] Account for byte width in m_PtrAdd The method has few uses yet, so just pass DL argument to it. The change follows m_PtrToIntSameSize, and I don't see a better way of delivering the byte width to the method. --- llvm/include/llvm/IR/PatternMatch.h | 13 ++ llvm/lib/Analysis/InstructionSimplify.cpp | 2 +- .../InstCombineSimplifyDemanded.cpp | 7 ++--- .../InstCombine/InstructionCombining.cpp | 2 +- llvm/unittests/IR/PatternMatch.cpp| 26 ++- 5 files changed, 34 insertions(+), 16 deletions(-) diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index ed9b83d5d4361..c5fb399070e02 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -1940,15 +1940,17 @@ struct m_SplatOrPoisonMask { }; template struct PtrAdd_match { + const DataLayout &DL; PointerOpTy PointerOp; OffsetOpTy OffsetOp; - PtrAdd_match(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp) - : PointerOp(PointerOp), OffsetOp(OffsetOp) {} + PtrAdd_match(const DataLayout &DL, const PointerOpTy &PointerOp, + const OffsetOpTy &OffsetOp) + : DL(DL), PointerOp(PointerOp), OffsetOp(OffsetOp) {} template bool match(OpTy *V) const { auto *GEP = dyn_cast(V); -return GEP && GEP->getSourceElementType()->isIntegerTy(8) && +return GEP && GEP->getSourceElementType()->isIntegerTy(DL.getByteWidth()) && PointerOp.match(GEP->getPointerOperand()) && OffsetOp.match(GEP->idx_begin()->get()); } @@ -1990,8 +1992,9 @@ inline auto m_GEP(const OperandTypes &...Ops) { /// Matches GEP with i8 source element type template inline PtrAdd_match -m_PtrAdd(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp) { - return PtrAdd_match(PointerOp, OffsetOp); +m_PtrAdd(const DataLayout &DL, const PointerOpTy &PointerOp, + const OffsetOpTy &OffsetOp) { + return PtrAdd_match(DL, PointerOp, OffsetOp); } //===--===// diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 82530e7d5b6c6..f310a5db5aee1 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -5389,7 +5389,7 @@ static Value *simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, // ptrtoint (ptradd (Ptr, X - ptrtoint(Ptr))) -> X Value *Ptr, *X; if (CastOpc == Instruction::PtrToInt && - match(Op, m_PtrAdd(m_Value(Ptr), + match(Op, m_PtrAdd(Q.DL, m_Value(Ptr), m_Sub(m_Value(X), m_PtrToInt(m_Deferred(Ptr) && X->getType() == Ty && Ty == Q.DL.getIndexType(Ptr->getType())) return X; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 0e3436d12702d..cc5b4f3cb63bf 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -991,9 +991,10 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I, Value *InnerPtr; uint64_t GEPIndex; uint64_t PtrMaskImmediate; -if (match(I, m_Intrinsic( - m_PtrAdd(m_Value(InnerPtr), m_ConstantInt(GEPIndex)), - m_ConstantInt(PtrMaskImmediate { +if (match(I, + m_Intrinsic( + m_PtrAdd(DL, m_Value(InnerPtr), m_ConstantInt(GEPIndex)), + m_ConstantInt(PtrMaskImmediate { LHSKnown = computeKnownBits(InnerPtr, I, Depth + 1); if (!LHSKnown.isZero()) { diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 91a1b61ddc483..66358359275d2 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2595,7 +2595,7 @@ static Instruction *canonicalizeGEPOfConstGEPI8(GetElementPtrInst &GEP, auto &DL = IC.getDataLayout(); Value *Base; const APInt *C1; - if (!match(Src, m_PtrAdd(m_Value(Base), m_APInt(C1 + if (!match(Src, m_PtrAdd(DL, m_Value(Base), m_APInt(C1 return nullptr; Value *VarIndex; const APInt *C2; diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp index bb7cc0802b1df..c88c01b9e5541 100644 --- a/llvm/unittests/IR/PatternMatch.cpp +++ b/llvm/unittests/IR/PatternMatch.cpp @@ -2599,26 +2599,40 @@ TEST_F(PatternMatchTest, ConstExpr) { EXPECT_TRUE(match(V, m_ConstantExpr())); } -TEST_F(PatternMatch
[llvm-branch-commits] [llvm] [ValueTracking] Make isBytewiseValue byte width agnostic (PR #106538)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106538 >From 4650b11d6d467e0ca66fed3cea61ed3d77f98fd4 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Fri, 2 Aug 2024 13:14:49 +0300 Subject: [PATCH] [ValueTracking] Make isBytewiseValue byte width agnostic This is a simple change to show how easy it can be to support unusual byte widths in the middle end. --- llvm/lib/Analysis/ValueTracking.cpp | 30 +++-- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 21f844c4d2f45..858d79b7f095b 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -6068,21 +6068,22 @@ bool llvm::canIgnoreSignBitOfNaN(const Use &U) { } Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { + unsigned ByteWidth = DL.getByteWidth(); // All byte-wide stores are splatable, even of arbitrary variables. - if (V->getType()->isIntegerTy(8)) + if (V->getType()->isIntegerTy(ByteWidth)) return V; LLVMContext &Ctx = V->getContext(); // Undef don't care. - auto *UndefInt8 = UndefValue::get(Type::getInt8Ty(Ctx)); + auto *UndefByte = UndefValue::get(Type::getIntNTy(Ctx, ByteWidth)); if (isa(V)) -return UndefInt8; +return UndefByte; // Return poison for zero-sized type. if (DL.getTypeStoreSize(V->getType()).isZero()) -return PoisonValue::get(Type::getInt8Ty(Ctx)); +return PoisonValue::get(Type::getIntNTy(Ctx, ByteWidth)); Constant *C = dyn_cast(V); if (!C) { @@ -6097,7 +6098,7 @@ Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { // Handle 'null' ConstantArrayZero etc. if (C->isNullValue()) -return Constant::getNullValue(Type::getInt8Ty(Ctx)); +return Constant::getNullValue(Type::getIntNTy(Ctx, ByteWidth)); // Constant floating-point values can be handled as integer values if the // corresponding integer value is "byteable". An important case is 0.0. @@ -6114,13 +6115,14 @@ Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { : nullptr; } - // We can handle constant integers that are multiple of 8 bits. + // We can handle constant integers that are multiple of the byte width. if (ConstantInt *CI = dyn_cast(C)) { -if (CI->getBitWidth() % 8 == 0) { - assert(CI->getBitWidth() > 8 && "8 bits should be handled above!"); - if (!CI->getValue().isSplat(8)) +if (CI->getBitWidth() % ByteWidth == 0) { + assert(CI->getBitWidth() > ByteWidth && + "single byte should be handled above!"); + if (!CI->getValue().isSplat(ByteWidth)) return nullptr; - return ConstantInt::get(Ctx, CI->getValue().trunc(8)); + return ConstantInt::get(Ctx, CI->getValue().trunc(ByteWidth)); } } @@ -6140,15 +6142,15 @@ Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { return LHS; if (!LHS || !RHS) return nullptr; -if (LHS == UndefInt8) +if (LHS == UndefByte) return RHS; -if (RHS == UndefInt8) +if (RHS == UndefByte) return LHS; return nullptr; }; if (ConstantDataSequential *CA = dyn_cast(C)) { -Value *Val = UndefInt8; +Value *Val = UndefByte; for (uint64_t I = 0, E = CA->getNumElements(); I != E; ++I) if (!(Val = Merge(Val, isBytewiseValue(CA->getElementAsConstant(I), DL return nullptr; @@ -6156,7 +6158,7 @@ Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { } if (isa(C)) { -Value *Val = UndefInt8; +Value *Val = UndefByte; for (Value *Op : C->operands()) if (!(Val = Merge(Val, isBytewiseValue(Op, DL return nullptr; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [SimplifyLibCalls] Add initial support for non-8-bit bytes (PR #106542)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106542 >From c46fbb92b0573dc5dd79b6da7b6955df8b7db7c8 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Wed, 28 Aug 2024 16:09:44 +0300 Subject: [PATCH] [SimplifyLibCalls] Add initial support for non-8-bit bytes The patch makes CharWidth argument of `getStringLength` mandatory and ensures the correct values are passed in most cases. This is *not* a complete support for unusual byte widths in SimplifyLibCalls since `getConstantStringInfo` returns false for those. The code guarded by `getConstantStringInfo` returning true is unchanged because the changes are currently not testable. --- llvm/include/llvm/Analysis/ValueTracking.h| 4 +- .../llvm/Transforms/Utils/SimplifyLibCalls.h | 4 +- llvm/lib/Analysis/MemoryBuiltins.cpp | 3 +- llvm/lib/Analysis/ValueTracking.cpp | 40 ++-- .../InstCombine/InstCombineCalls.cpp | 12 +- .../InstCombine/InstructionCombining.cpp | 5 +- .../lib/Transforms/Utils/SimplifyLibCalls.cpp | 191 -- .../InstCombine/SimplifyLibCalls/fputs-b16.ll | 19 ++ .../SimplifyLibCalls/fwrite-b16.ll| 19 ++ .../SimplifyLibCalls/memchr-b16.ll| 34 .../SimplifyLibCalls/memcmp-b32.ll| 32 +++ .../SimplifyLibCalls/memcpy-b16.ll| 69 +++ .../SimplifyLibCalls/memcpy_chk-b16.ll| 17 ++ .../SimplifyLibCalls/mempcpy-b16.ll | 17 ++ .../SimplifyLibCalls/memrchr-b16.ll | 20 ++ .../SimplifyLibCalls/memset-b16.ll| 66 ++ .../SimplifyLibCalls/stpcpy-b16.ll| 31 +++ .../SimplifyLibCalls/stpcpy_chk-b16.ll| 44 .../SimplifyLibCalls/stpncpy-b16.ll | 47 + .../SimplifyLibCalls/strcat-b16.ll| 20 ++ .../SimplifyLibCalls/strchr-b16.ll| 45 + .../SimplifyLibCalls/strcmp-b32.ll| 50 + .../SimplifyLibCalls/strcpy-b16.ll| 18 ++ .../SimplifyLibCalls/strcpy_chk-b16.ll| 30 +++ .../SimplifyLibCalls/strlcpy-b16.ll | 18 ++ .../SimplifyLibCalls/strlen-b16.ll| 16 ++ .../SimplifyLibCalls/strncat-b16.ll | 20 ++ .../SimplifyLibCalls/strncmp-b32.ll | 34 .../SimplifyLibCalls/strncpy-b16.ll | 43 .../SimplifyLibCalls/strndup-b16.ll | 17 ++ .../SimplifyLibCalls/strnlen-b16.ll | 18 ++ .../SimplifyLibCalls/wcslen-b16.ll| 19 ++ llvm/test/Transforms/InstCombine/bcmp-1.ll| 2 +- llvm/test/Transforms/InstCombine/memcmp-1.ll | 2 +- llvm/test/Transforms/InstCombine/strncmp-1.ll | 2 +- 35 files changed, 928 insertions(+), 100 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/fputs-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/fwrite-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memchr-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memcmp-b32.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memcpy_chk-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/mempcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memrchr-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memset-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/stpcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/stpcpy_chk-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/stpncpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcat-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strchr-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcmp-b32.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcpy_chk-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strlcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strlen-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strncat-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strncmp-b32.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strncpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strndup-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strnlen-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/wcslen-b16.ll diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h index
[llvm-branch-commits] [llvm] [mlir] [IR] Make @llvm.memset prototype byte width dependent (PR #106537)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106537 >From 2080c3eacf59f6a63aa8b400af9e1177f6f52cbd Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Thu, 1 Aug 2024 23:47:25 +0300 Subject: [PATCH] [IR] Make @llvm.memset prototype byte width dependent This patch changes the type of the value argument of @llvm.memset and similar intrinsics from i8 to iN, where N is the byte width specified in data layout string. Note that the argument still has fixed type (not overloaded), but type checker will complain if the type does not match the byte width. Ideally, the type of the argument would be dependent on the address space of the pointer argument. It is easy to do this (and I did it downstream as a PoC), but since data layout string doesn't currently allow different byte widths for different address spaces, I refrained from doing it now. --- llvm/include/llvm-c/Core.h| 2 +- llvm/include/llvm/IR/Intrinsics.h | 13 ++-- llvm/include/llvm/IR/Intrinsics.td| 13 ++-- llvm/lib/AsmParser/LLParser.cpp | 4 +- llvm/lib/IR/AutoUpgrade.cpp | 4 +- llvm/lib/IR/Core.cpp | 4 +- llvm/lib/IR/Function.cpp | 4 +- llvm/lib/IR/IRBuilder.cpp | 2 +- llvm/lib/IR/Intrinsics.cpp| 61 +++ llvm/lib/IR/Verifier.cpp | 2 +- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 3 +- .../NumericalStabilitySanitizer.cpp | 2 +- .../LLVMIR/LLVMToLLVMIRTranslation.cpp| 4 +- 13 files changed, 71 insertions(+), 47 deletions(-) diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index d645646289025..4ecc657837910 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -2930,7 +2930,7 @@ LLVM_C_ABI LLVMValueRef LLVMGetIntrinsicDeclaration(LLVMModuleRef Mod, * * @see llvm::Intrinsic::getType() */ -LLVM_C_ABI LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID, +LLVM_C_ABI LLVMTypeRef LLVMIntrinsicGetType(LLVMModuleRef Mod, unsigned ID, LLVMTypeRef *ParamTypes, size_t ParamCount); diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h index 156805293367b..bce5090fd3b97 100644 --- a/llvm/include/llvm/IR/Intrinsics.h +++ b/llvm/include/llvm/IR/Intrinsics.h @@ -23,6 +23,7 @@ namespace llvm { +class DataLayout; class Type; class FunctionType; class Function; @@ -75,7 +76,7 @@ namespace Intrinsic { LLVM_ABI std::string getNameNoUnnamedTypes(ID Id, ArrayRef Tys); /// Return the function type for an intrinsic. - LLVM_ABI FunctionType *getType(LLVMContext &Context, ID id, + LLVM_ABI FunctionType *getType(const Module *M, ID id, ArrayRef Tys = {}); /// Returns true if the intrinsic can be overloaded. @@ -141,6 +142,7 @@ namespace Intrinsic { struct IITDescriptor { enum IITDescriptorKind { Void, + Byte, VarArg, MMX, Token, @@ -253,9 +255,9 @@ namespace Intrinsic { /// /// Returns false if the given type matches with the constraints, true /// otherwise. - LLVM_ABI MatchIntrinsicTypesResult - matchIntrinsicSignature(FunctionType *FTy, ArrayRef &Infos, - SmallVectorImpl &ArgTys); + LLVM_ABI MatchIntrinsicTypesResult matchIntrinsicSignature( + const DataLayout &DL, FunctionType *FTy, ArrayRef &Infos, + SmallVectorImpl &ArgTys); /// Verify if the intrinsic has variable arguments. This method is intended to /// be called after all the fixed arguments have been matched first. @@ -270,7 +272,8 @@ namespace Intrinsic { /// /// Returns false if the given ID and function type combination is not a /// valid intrinsic call. - LLVM_ABI bool getIntrinsicSignature(Intrinsic::ID, FunctionType *FT, + LLVM_ABI bool getIntrinsicSignature(const DataLayout &DL, Intrinsic::ID, + FunctionType *FT, SmallVectorImpl &ArgTys); /// Same as previous, but accepts a Function instead of ID and FunctionType. diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index bd6f94ac1286c..438910fd2aef5 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -308,6 +308,7 @@ def IIT_V1 : IIT_Vec<1, 28>; def IIT_VARARG : IIT_VT; def IIT_ONE_NTH_ELTS_VEC_ARG : IIT_Base<30>; def IIT_SAME_VEC_WIDTH_ARG : IIT_Base<31>; +def IIT_BYTE : IIT_Base<32>; def IIT_VEC_OF_ANYPTRS_TO_ELT : IIT_Base<34>; def IIT_I128 : IIT_Int<128, 35>; def IIT_V512 : IIT_Vec<512, 36>; @@ -392,6 +393,10 @@ class LLVMType { !foreach(iit, IITs, iit.Number)); } +class LLVMByteType : LLVMType { + let Sig = [IIT_BYTE.Number]; +} + class LLVMAnyType : LLVMType { le
[llvm-branch-commits] [llvm] [SimplifyLibCalls] Add initial support for non-8-bit bytes (PR #106542)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106542 >From 4bf7017413eafc29a432941a56cb7356074828f7 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Wed, 28 Aug 2024 16:09:44 +0300 Subject: [PATCH] [SimplifyLibCalls] Add initial support for non-8-bit bytes The patch makes CharWidth argument of `getStringLength` mandatory and ensures the correct values are passed in most cases. This is *not* a complete support for unusual byte widths in SimplifyLibCalls since `getConstantStringInfo` returns false for those. The code guarded by `getConstantStringInfo` returning true is unchanged because the changes are currently not testable. --- llvm/include/llvm/Analysis/ValueTracking.h| 4 +- .../llvm/Transforms/Utils/SimplifyLibCalls.h | 4 +- llvm/lib/Analysis/MemoryBuiltins.cpp | 3 +- llvm/lib/Analysis/ValueTracking.cpp | 40 ++-- .../InstCombine/InstCombineCalls.cpp | 12 +- .../InstCombine/InstructionCombining.cpp | 5 +- .../lib/Transforms/Utils/SimplifyLibCalls.cpp | 191 -- .../InstCombine/SimplifyLibCalls/fputs-b16.ll | 19 ++ .../SimplifyLibCalls/fwrite-b16.ll| 19 ++ .../SimplifyLibCalls/memchr-b16.ll| 34 .../SimplifyLibCalls/memcmp-b32.ll| 32 +++ .../SimplifyLibCalls/memcpy-b16.ll| 69 +++ .../SimplifyLibCalls/memcpy_chk-b16.ll| 17 ++ .../SimplifyLibCalls/mempcpy-b16.ll | 17 ++ .../SimplifyLibCalls/memrchr-b16.ll | 20 ++ .../SimplifyLibCalls/memset-b16.ll| 66 ++ .../SimplifyLibCalls/stpcpy-b16.ll| 31 +++ .../SimplifyLibCalls/stpcpy_chk-b16.ll| 44 .../SimplifyLibCalls/stpncpy-b16.ll | 47 + .../SimplifyLibCalls/strcat-b16.ll| 20 ++ .../SimplifyLibCalls/strchr-b16.ll| 45 + .../SimplifyLibCalls/strcmp-b32.ll| 50 + .../SimplifyLibCalls/strcpy-b16.ll| 18 ++ .../SimplifyLibCalls/strcpy_chk-b16.ll| 30 +++ .../SimplifyLibCalls/strlcpy-b16.ll | 18 ++ .../SimplifyLibCalls/strlen-b16.ll| 16 ++ .../SimplifyLibCalls/strncat-b16.ll | 20 ++ .../SimplifyLibCalls/strncmp-b32.ll | 34 .../SimplifyLibCalls/strncpy-b16.ll | 43 .../SimplifyLibCalls/strndup-b16.ll | 17 ++ .../SimplifyLibCalls/strnlen-b16.ll | 18 ++ .../SimplifyLibCalls/wcslen-b16.ll| 19 ++ llvm/test/Transforms/InstCombine/bcmp-1.ll| 2 +- llvm/test/Transforms/InstCombine/memcmp-1.ll | 2 +- llvm/test/Transforms/InstCombine/strncmp-1.ll | 2 +- 35 files changed, 928 insertions(+), 100 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/fputs-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/fwrite-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memchr-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memcmp-b32.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memcpy_chk-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/mempcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memrchr-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memset-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/stpcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/stpcpy_chk-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/stpncpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcat-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strchr-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcmp-b32.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcpy_chk-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strlcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strlen-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strncat-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strncmp-b32.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strncpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strndup-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strnlen-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/wcslen-b16.ll diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h index
[llvm-branch-commits] [clang] [llvm] [ValueTracking] Add CharWidth argument to getConstantStringInfo (NFC) (PR #106541)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106541 >From b878d8834e17681c4d53f2b65c6ed7b24d89f3c4 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Wed, 28 Aug 2024 23:51:13 +0300 Subject: [PATCH] [ValueTracking] Add CharWidth argument to getConstantStringInfo (NFC) The method assumes that host chars and target chars have the same width. Add a CharWidth argument so that it can bail out if the requested char width differs from the host char width. Alternatively, the check could be done at call sites, but this is more error-prone. In the future, this method will be replaced with a different one that allows host/target chars to have different widths. The prototype will be the same except that StringRef is replaced with something that is byte width agnostic. Adding CharWidth argument now reduces the future diff. --- clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp | 4 +- llvm/include/llvm/Analysis/ValueTracking.h| 2 +- llvm/lib/Analysis/ValueTracking.cpp | 7 +- .../AMDGPU/AMDGPUPrintfRuntimeBinding.cpp | 4 +- llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp | 2 +- .../Target/SPIRV/SPIRVPrepareFunctions.cpp| 2 +- .../WebAssembly/WebAssemblyAsmPrinter.cpp | 2 +- .../AggressiveInstCombine.cpp | 12 +- .../lib/Transforms/Utils/AMDGPUEmitPrintf.cpp | 4 +- .../lib/Transforms/Utils/SimplifyLibCalls.cpp | 103 -- 10 files changed, 96 insertions(+), 46 deletions(-) diff --git a/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp b/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp index f09b3b92c4ea0..b7b65634238c4 100644 --- a/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp @@ -226,7 +226,7 @@ void CodeGenFunction::ProcessOrderScopeAMDGCN(Value *Order, Value *Scope, // Some of the atomic builtins take the scope as a string name. StringRef scp; - if (llvm::getConstantStringInfo(Scope, scp)) { + if (llvm::getConstantStringInfo(Scope, scp, /*CharWidth=*/8)) { SSID = getLLVMContext().getOrInsertSyncScopeID(scp); return; } @@ -281,7 +281,7 @@ void CodeGenFunction::AddAMDGPUFenceAddressSpaceMMRA(llvm::Instruction *Inst, for (unsigned K = 2; K < E->getNumArgs(); ++K) { llvm::Value *V = EmitScalarExpr(E->getArg(K)); StringRef AS; -if (llvm::getConstantStringInfo(V, AS)) { +if (llvm::getConstantStringInfo(V, AS, /*CharWidth=*/8)) { MMRAs.push_back({Tag, AS}); // TODO: Delete the resulting unused constant? continue; diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h index 02990a3cb44f7..e6fb3cb9bd044 100644 --- a/llvm/include/llvm/Analysis/ValueTracking.h +++ b/llvm/include/llvm/Analysis/ValueTracking.h @@ -404,7 +404,7 @@ LLVM_ABI bool getConstantDataArrayInfo(const Value *V, /// trailing null characters as well as any other characters that come after /// it. LLVM_ABI bool getConstantStringInfo(const Value *V, StringRef &Str, -bool TrimAtNul = true); +unsigned CharWidth, bool TrimAtNul = true); /// If we can compute the length of the string pointed to by the specified /// pointer, return 'len+1'. If we can't, return 0. diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 858d79b7f095b..ed202b8a1f6e5 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -6457,9 +6457,12 @@ bool llvm::getConstantDataArrayInfo(const Value *V, /// return true. When TrimAtNul is set, Str will contain only the bytes up /// to but not including the first nul. Return false on failure. bool llvm::getConstantStringInfo(const Value *V, StringRef &Str, - bool TrimAtNul) { + unsigned CharWidth, bool TrimAtNul) { + if (CharWidth != CHAR_BIT) +return false; + ConstantDataArraySlice Slice; - if (!getConstantDataArrayInfo(V, Slice, 8)) + if (!getConstantDataArrayInfo(V, Slice, CharWidth)) return false; if (Slice.Array == nullptr) { diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp index 7a2a7fc250e27..471dfbc53274c 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp @@ -121,7 +121,7 @@ static_assert(NonLiteralStr.size() == 3); static StringRef getAsConstantStr(Value *V) { StringRef S; - if (!getConstantStringInfo(V, S)) + if (!getConstantStringInfo(V, S, /*CharWidth=*/8)) S = NonLiteralStr; return S; @@ -154,7 +154,7 @@ bool AMDGPUPrintfRuntimeBindingImpl::lowerPrintfForGpu(Module &M) { Value *Op = CI->getArgOperand(0); StringRef FormatStr; -if (!getConstantStringInfo(Op, FormatStr)) { +if (!getConstantStringInfo(Op, FormatStr, /*CharWidth=*/8)) { V
[llvm-branch-commits] [llvm] [IR] Account for byte width in m_PtrAdd (PR #106540)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106540 >From 68b0d700521ba040347ad0a04cf2e090fdd81d93 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Thu, 29 Aug 2024 00:54:20 +0300 Subject: [PATCH] [IR] Account for byte width in m_PtrAdd The method has few uses yet, so just pass DL argument to it. The change follows m_PtrToIntSameSize, and I don't see a better way of delivering the byte width to the method. --- llvm/include/llvm/IR/PatternMatch.h | 13 ++ llvm/lib/Analysis/InstructionSimplify.cpp | 2 +- .../InstCombineSimplifyDemanded.cpp | 7 ++--- .../InstCombine/InstructionCombining.cpp | 2 +- llvm/unittests/IR/PatternMatch.cpp| 26 ++- 5 files changed, 34 insertions(+), 16 deletions(-) diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index ed9b83d5d4361..c5fb399070e02 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -1940,15 +1940,17 @@ struct m_SplatOrPoisonMask { }; template struct PtrAdd_match { + const DataLayout &DL; PointerOpTy PointerOp; OffsetOpTy OffsetOp; - PtrAdd_match(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp) - : PointerOp(PointerOp), OffsetOp(OffsetOp) {} + PtrAdd_match(const DataLayout &DL, const PointerOpTy &PointerOp, + const OffsetOpTy &OffsetOp) + : DL(DL), PointerOp(PointerOp), OffsetOp(OffsetOp) {} template bool match(OpTy *V) const { auto *GEP = dyn_cast(V); -return GEP && GEP->getSourceElementType()->isIntegerTy(8) && +return GEP && GEP->getSourceElementType()->isIntegerTy(DL.getByteWidth()) && PointerOp.match(GEP->getPointerOperand()) && OffsetOp.match(GEP->idx_begin()->get()); } @@ -1990,8 +1992,9 @@ inline auto m_GEP(const OperandTypes &...Ops) { /// Matches GEP with i8 source element type template inline PtrAdd_match -m_PtrAdd(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp) { - return PtrAdd_match(PointerOp, OffsetOp); +m_PtrAdd(const DataLayout &DL, const PointerOpTy &PointerOp, + const OffsetOpTy &OffsetOp) { + return PtrAdd_match(DL, PointerOp, OffsetOp); } //===--===// diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 82530e7d5b6c6..f310a5db5aee1 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -5389,7 +5389,7 @@ static Value *simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, // ptrtoint (ptradd (Ptr, X - ptrtoint(Ptr))) -> X Value *Ptr, *X; if (CastOpc == Instruction::PtrToInt && - match(Op, m_PtrAdd(m_Value(Ptr), + match(Op, m_PtrAdd(Q.DL, m_Value(Ptr), m_Sub(m_Value(X), m_PtrToInt(m_Deferred(Ptr) && X->getType() == Ty && Ty == Q.DL.getIndexType(Ptr->getType())) return X; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 0e3436d12702d..cc5b4f3cb63bf 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -991,9 +991,10 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I, Value *InnerPtr; uint64_t GEPIndex; uint64_t PtrMaskImmediate; -if (match(I, m_Intrinsic( - m_PtrAdd(m_Value(InnerPtr), m_ConstantInt(GEPIndex)), - m_ConstantInt(PtrMaskImmediate { +if (match(I, + m_Intrinsic( + m_PtrAdd(DL, m_Value(InnerPtr), m_ConstantInt(GEPIndex)), + m_ConstantInt(PtrMaskImmediate { LHSKnown = computeKnownBits(InnerPtr, I, Depth + 1); if (!LHSKnown.isZero()) { diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 91a1b61ddc483..66358359275d2 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2595,7 +2595,7 @@ static Instruction *canonicalizeGEPOfConstGEPI8(GetElementPtrInst &GEP, auto &DL = IC.getDataLayout(); Value *Base; const APInt *C1; - if (!match(Src, m_PtrAdd(m_Value(Base), m_APInt(C1 + if (!match(Src, m_PtrAdd(DL, m_Value(Base), m_APInt(C1 return nullptr; Value *VarIndex; const APInt *C2; diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp index bb7cc0802b1df..c88c01b9e5541 100644 --- a/llvm/unittests/IR/PatternMatch.cpp +++ b/llvm/unittests/IR/PatternMatch.cpp @@ -2599,26 +2599,40 @@ TEST_F(PatternMatchTest, ConstExpr) { EXPECT_TRUE(match(V, m_ConstantExpr())); } -TEST_F(PatternMatch
[llvm-branch-commits] [llvm] [IRBuilder] Add getByteTy and use it in CreatePtrAdd (PR #106539)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106539 >From 1655f416864eb0c5849d96aa10c1eb9214aecf5c Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Thu, 22 Aug 2024 15:10:58 +0300 Subject: [PATCH] [IRBuilder] Add getByteTy and use it in CreatePtrAdd The change requires DataLayout instance to be available, which, in turn, requires insertion point to be set. In-tree tests detected only one case when the function was called without setting an insertion point, it was changed to create a constant expression directly. --- llvm/include/llvm/IR/IRBuilder.h | 10 +++-- .../Instrumentation/SanitizerCoverage.cpp | 5 ++--- llvm/unittests/IR/IRBuilderTest.cpp | 22 +++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index 7c600e762a451..b0c60056e740d 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -543,6 +543,12 @@ class IRBuilderBase { // Type creation methods //======// + /// Fetch the type representing a byte. + IntegerType *getByteTy() { +const DataLayout &DL = BB->getDataLayout(); +return Type::getIntNTy(Context, DL.getByteWidth()); + } + /// Fetch the type representing a single bit IntegerType *getInt1Ty() { return Type::getInt1Ty(Context); @@ -2040,12 +2046,12 @@ class IRBuilderBase { Value *CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name = "", GEPNoWrapFlags NW = GEPNoWrapFlags::none()) { -return CreateGEP(getInt8Ty(), Ptr, Offset, Name, NW); +return CreateGEP(getByteTy(), Ptr, Offset, Name, NW); } Value *CreateInBoundsPtrAdd(Value *Ptr, Value *Offset, const Twine &Name = "") { -return CreateGEP(getInt8Ty(), Ptr, Offset, Name, +return CreateGEP(getByteTy(), Ptr, Offset, Name, GEPNoWrapFlags::inBounds()); } diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index 5b8ea1547ca2f..a45b56696f612 100644 --- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -357,14 +357,13 @@ ModuleSanitizerCoverage::CreateSecStartEnd(Module &M, const char *Section, GlobalVariable *SecEnd = new GlobalVariable(M, Ty, false, Linkage, nullptr, getSectionEnd(Section)); SecEnd->setVisibility(GlobalValue::HiddenVisibility); - IRBuilder<> IRB(M.getContext()); if (!TargetTriple.isOSBinFormatCOFF()) return std::make_pair(SecStart, SecEnd); // Account for the fact that on windows-msvc __start_* symbols actually // point to a uint64_t before the start of the array. - auto GEP = - IRB.CreatePtrAdd(SecStart, ConstantInt::get(IntptrTy, sizeof(uint64_t))); + Constant *GEP = ConstantExpr::getGetElementPtr( + Int8Ty, SecStart, ConstantInt::get(IntptrTy, sizeof(uint64_t))); return std::make_pair(GEP, SecEnd); } diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp index 4f2ede3321080..9a0be982b2175 100644 --- a/llvm/unittests/IR/IRBuilderTest.cpp +++ b/llvm/unittests/IR/IRBuilderTest.cpp @@ -525,6 +525,14 @@ TEST_F(IRBuilderTest, DataLayout) { EXPECT_FALSE(M->getDataLayout().isLegalInteger(32)); } +TEST_F(IRBuilderTest, GetByteTy) { + IRBuilder<> Builder(BB); + + EXPECT_TRUE(Builder.getByteTy()->isIntegerTy(8)); + M->setDataLayout("b:32"); + EXPECT_TRUE(Builder.getByteTy()->isIntegerTy(32)); +} + TEST_F(IRBuilderTest, GetIntTy) { IRBuilder<> Builder(BB); IntegerType *Ty1 = Builder.getInt1Ty(); @@ -536,6 +544,20 @@ TEST_F(IRBuilderTest, GetIntTy) { EXPECT_EQ(IntPtrTy, IntegerType::get(Ctx, IntPtrBitSize)); } +TEST_F(IRBuilderTest, CreatePtrAdd) { + IRBuilder<> Builder(BB); + + M->setDataLayout("b:16-p:32:32"); + Value *V = Builder.CreatePtrAdd(GV, ConstantInt::get(Ctx, APInt(32, 42))); + ASSERT_TRUE(isa(V)); + EXPECT_TRUE(cast(V)->getResultElementType()->isIntegerTy(16)); + + M->setDataLayout("b:32-p:64:32"); + V = Builder.CreateInBoundsPtrAdd(GV, ConstantInt::get(Ctx, APInt(64, 42))); + ASSERT_TRUE(isa(V)); + EXPECT_TRUE(cast(V)->getResultElementType()->isIntegerTy(32)); +} + TEST_F(IRBuilderTest, UnaryOperators) { IRBuilder Builder(BB); Value *V = Builder.CreateLoad(GV->getValueType(), GV); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [ValueTracking] Make isBytewiseValue byte width agnostic (PR #106538)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106538 >From 1f681888e8eb5629894a094755bc0c596cf62e6a Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Fri, 2 Aug 2024 13:14:49 +0300 Subject: [PATCH] [ValueTracking] Make isBytewiseValue byte width agnostic This is a simple change to show how easy it can be to support unusual byte widths in the middle end. --- llvm/lib/Analysis/ValueTracking.cpp | 30 +++-- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 21f844c4d2f45..858d79b7f095b 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -6068,21 +6068,22 @@ bool llvm::canIgnoreSignBitOfNaN(const Use &U) { } Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { + unsigned ByteWidth = DL.getByteWidth(); // All byte-wide stores are splatable, even of arbitrary variables. - if (V->getType()->isIntegerTy(8)) + if (V->getType()->isIntegerTy(ByteWidth)) return V; LLVMContext &Ctx = V->getContext(); // Undef don't care. - auto *UndefInt8 = UndefValue::get(Type::getInt8Ty(Ctx)); + auto *UndefByte = UndefValue::get(Type::getIntNTy(Ctx, ByteWidth)); if (isa(V)) -return UndefInt8; +return UndefByte; // Return poison for zero-sized type. if (DL.getTypeStoreSize(V->getType()).isZero()) -return PoisonValue::get(Type::getInt8Ty(Ctx)); +return PoisonValue::get(Type::getIntNTy(Ctx, ByteWidth)); Constant *C = dyn_cast(V); if (!C) { @@ -6097,7 +6098,7 @@ Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { // Handle 'null' ConstantArrayZero etc. if (C->isNullValue()) -return Constant::getNullValue(Type::getInt8Ty(Ctx)); +return Constant::getNullValue(Type::getIntNTy(Ctx, ByteWidth)); // Constant floating-point values can be handled as integer values if the // corresponding integer value is "byteable". An important case is 0.0. @@ -6114,13 +6115,14 @@ Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { : nullptr; } - // We can handle constant integers that are multiple of 8 bits. + // We can handle constant integers that are multiple of the byte width. if (ConstantInt *CI = dyn_cast(C)) { -if (CI->getBitWidth() % 8 == 0) { - assert(CI->getBitWidth() > 8 && "8 bits should be handled above!"); - if (!CI->getValue().isSplat(8)) +if (CI->getBitWidth() % ByteWidth == 0) { + assert(CI->getBitWidth() > ByteWidth && + "single byte should be handled above!"); + if (!CI->getValue().isSplat(ByteWidth)) return nullptr; - return ConstantInt::get(Ctx, CI->getValue().trunc(8)); + return ConstantInt::get(Ctx, CI->getValue().trunc(ByteWidth)); } } @@ -6140,15 +6142,15 @@ Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { return LHS; if (!LHS || !RHS) return nullptr; -if (LHS == UndefInt8) +if (LHS == UndefByte) return RHS; -if (RHS == UndefInt8) +if (RHS == UndefByte) return LHS; return nullptr; }; if (ConstantDataSequential *CA = dyn_cast(C)) { -Value *Val = UndefInt8; +Value *Val = UndefByte; for (uint64_t I = 0, E = CA->getNumElements(); I != E; ++I) if (!(Val = Merge(Val, isBytewiseValue(CA->getElementAsConstant(I), DL return nullptr; @@ -6156,7 +6158,7 @@ Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { } if (isa(C)) { -Value *Val = UndefInt8; +Value *Val = UndefByte; for (Value *Op : C->operands()) if (!(Val = Merge(Val, isBytewiseValue(Op, DL return nullptr; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [mlir] [IR] Make @llvm.memset prototype byte width dependent (PR #106537)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106537 >From 28662b70cdb4dbd2aafe3feddd2a09e14ea018aa Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Thu, 1 Aug 2024 23:47:25 +0300 Subject: [PATCH] [IR] Make @llvm.memset prototype byte width dependent This patch changes the type of the value argument of @llvm.memset and similar intrinsics from i8 to iN, where N is the byte width specified in data layout string. Note that the argument still has fixed type (not overloaded), but type checker will complain if the type does not match the byte width. Ideally, the type of the argument would be dependent on the address space of the pointer argument. It is easy to do this (and I did it downstream as a PoC), but since data layout string doesn't currently allow different byte widths for different address spaces, I refrained from doing it now. --- llvm/include/llvm-c/Core.h| 2 +- llvm/include/llvm/IR/Intrinsics.h | 14 +++-- llvm/include/llvm/IR/Intrinsics.td| 13 ++-- llvm/lib/AsmParser/LLParser.cpp | 4 +- llvm/lib/IR/AutoUpgrade.cpp | 4 +- llvm/lib/IR/Core.cpp | 4 +- llvm/lib/IR/Function.cpp | 4 +- llvm/lib/IR/IRBuilder.cpp | 2 +- llvm/lib/IR/Intrinsics.cpp| 61 +++ llvm/lib/IR/Verifier.cpp | 2 +- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 3 +- .../NumericalStabilitySanitizer.cpp | 2 +- .../LLVMIR/LLVMToLLVMIRTranslation.cpp| 4 +- 13 files changed, 71 insertions(+), 48 deletions(-) diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index d645646289025..4ecc657837910 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -2930,7 +2930,7 @@ LLVM_C_ABI LLVMValueRef LLVMGetIntrinsicDeclaration(LLVMModuleRef Mod, * * @see llvm::Intrinsic::getType() */ -LLVM_C_ABI LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID, +LLVM_C_ABI LLVMTypeRef LLVMIntrinsicGetType(LLVMModuleRef Mod, unsigned ID, LLVMTypeRef *ParamTypes, size_t ParamCount); diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h index 156805293367b..896c952c95c14 100644 --- a/llvm/include/llvm/IR/Intrinsics.h +++ b/llvm/include/llvm/IR/Intrinsics.h @@ -23,6 +23,7 @@ namespace llvm { +class DataLayout; class Type; class FunctionType; class Function; @@ -75,8 +76,7 @@ namespace Intrinsic { LLVM_ABI std::string getNameNoUnnamedTypes(ID Id, ArrayRef Tys); /// Return the function type for an intrinsic. - LLVM_ABI FunctionType *getType(LLVMContext &Context, ID id, - ArrayRef Tys = {}); + LLVM_ABI FunctionType *getType(Module *M, ID id, ArrayRef Tys = {}); /// Returns true if the intrinsic can be overloaded. LLVM_ABI bool isOverloaded(ID id); @@ -141,6 +141,7 @@ namespace Intrinsic { struct IITDescriptor { enum IITDescriptorKind { Void, + Byte, VarArg, MMX, Token, @@ -253,9 +254,9 @@ namespace Intrinsic { /// /// Returns false if the given type matches with the constraints, true /// otherwise. - LLVM_ABI MatchIntrinsicTypesResult - matchIntrinsicSignature(FunctionType *FTy, ArrayRef &Infos, - SmallVectorImpl &ArgTys); + LLVM_ABI MatchIntrinsicTypesResult matchIntrinsicSignature( + const DataLayout &DL, FunctionType *FTy, ArrayRef &Infos, + SmallVectorImpl &ArgTys); /// Verify if the intrinsic has variable arguments. This method is intended to /// be called after all the fixed arguments have been matched first. @@ -270,7 +271,8 @@ namespace Intrinsic { /// /// Returns false if the given ID and function type combination is not a /// valid intrinsic call. - LLVM_ABI bool getIntrinsicSignature(Intrinsic::ID, FunctionType *FT, + LLVM_ABI bool getIntrinsicSignature(const DataLayout &DL, Intrinsic::ID, + FunctionType *FT, SmallVectorImpl &ArgTys); /// Same as previous, but accepts a Function instead of ID and FunctionType. diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index bd6f94ac1286c..438910fd2aef5 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -308,6 +308,7 @@ def IIT_V1 : IIT_Vec<1, 28>; def IIT_VARARG : IIT_VT; def IIT_ONE_NTH_ELTS_VEC_ARG : IIT_Base<30>; def IIT_SAME_VEC_WIDTH_ARG : IIT_Base<31>; +def IIT_BYTE : IIT_Base<32>; def IIT_VEC_OF_ANYPTRS_TO_ELT : IIT_Base<34>; def IIT_I128 : IIT_Int<128, 35>; def IIT_V512 : IIT_Vec<512, 36>; @@ -392,6 +393,10 @@ class LLVMType { !foreach(iit, IITs, iit.Number)); } +class LLVMByteType : LLVMType { + let Sig = [IIT_BYT
[llvm-branch-commits] [llvm] [SimplifyLibCalls] Add initial support for non-8-bit bytes (PR #106542)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106542 >From d2b8f2e23d50c638c31c787003c0e67feac98f18 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Wed, 28 Aug 2024 16:09:44 +0300 Subject: [PATCH] [SimplifyLibCalls] Add initial support for non-8-bit bytes The patch makes CharWidth argument of `getStringLength` mandatory and ensures the correct values are passed in most cases. This is *not* a complete support for unusual byte widths in SimplifyLibCalls since `getConstantStringInfo` returns false for those. The code guarded by `getConstantStringInfo` returning true is unchanged because the changes are currently not testable. --- llvm/include/llvm/Analysis/ValueTracking.h| 4 +- .../llvm/Transforms/Utils/SimplifyLibCalls.h | 4 +- llvm/lib/Analysis/MemoryBuiltins.cpp | 3 +- llvm/lib/Analysis/ValueTracking.cpp | 40 ++-- .../InstCombine/InstCombineCalls.cpp | 12 +- .../InstCombine/InstructionCombining.cpp | 5 +- .../lib/Transforms/Utils/SimplifyLibCalls.cpp | 191 -- .../InstCombine/SimplifyLibCalls/fputs-b16.ll | 19 ++ .../SimplifyLibCalls/fwrite-b16.ll| 19 ++ .../SimplifyLibCalls/memchr-b16.ll| 34 .../SimplifyLibCalls/memcmp-b32.ll| 32 +++ .../SimplifyLibCalls/memcpy-b16.ll| 69 +++ .../SimplifyLibCalls/memcpy_chk-b16.ll| 17 ++ .../SimplifyLibCalls/mempcpy-b16.ll | 17 ++ .../SimplifyLibCalls/memrchr-b16.ll | 20 ++ .../SimplifyLibCalls/memset-b16.ll| 66 ++ .../SimplifyLibCalls/stpcpy-b16.ll| 31 +++ .../SimplifyLibCalls/stpcpy_chk-b16.ll| 44 .../SimplifyLibCalls/stpncpy-b16.ll | 47 + .../SimplifyLibCalls/strcat-b16.ll| 20 ++ .../SimplifyLibCalls/strchr-b16.ll| 45 + .../SimplifyLibCalls/strcmp-b32.ll| 50 + .../SimplifyLibCalls/strcpy-b16.ll| 18 ++ .../SimplifyLibCalls/strcpy_chk-b16.ll| 30 +++ .../SimplifyLibCalls/strlcpy-b16.ll | 18 ++ .../SimplifyLibCalls/strlen-b16.ll| 16 ++ .../SimplifyLibCalls/strncat-b16.ll | 20 ++ .../SimplifyLibCalls/strncmp-b32.ll | 34 .../SimplifyLibCalls/strncpy-b16.ll | 43 .../SimplifyLibCalls/strndup-b16.ll | 17 ++ .../SimplifyLibCalls/strnlen-b16.ll | 18 ++ .../SimplifyLibCalls/wcslen-b16.ll| 19 ++ llvm/test/Transforms/InstCombine/bcmp-1.ll| 2 +- llvm/test/Transforms/InstCombine/memcmp-1.ll | 2 +- llvm/test/Transforms/InstCombine/strncmp-1.ll | 2 +- 35 files changed, 928 insertions(+), 100 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/fputs-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/fwrite-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memchr-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memcmp-b32.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memcpy_chk-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/mempcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memrchr-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/memset-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/stpcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/stpcpy_chk-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/stpncpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcat-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strchr-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcmp-b32.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strcpy_chk-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strlcpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strlen-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strncat-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strncmp-b32.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strncpy-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strndup-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/strnlen-b16.ll create mode 100644 llvm/test/Transforms/InstCombine/SimplifyLibCalls/wcslen-b16.ll diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h index
[llvm-branch-commits] [clang] [llvm] [ValueTracking] Add CharWidth argument to getConstantStringInfo (NFC) (PR #106541)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106541 >From 0a21746432336f2460bb916ede9cdb1a1ea61dd6 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Wed, 28 Aug 2024 23:51:13 +0300 Subject: [PATCH] [ValueTracking] Add CharWidth argument to getConstantStringInfo (NFC) The method assumes that host chars and target chars have the same width. Add a CharWidth argument so that it can bail out if the requested char width differs from the host char width. Alternatively, the check could be done at call sites, but this is more error-prone. In the future, this method will be replaced with a different one that allows host/target chars to have different widths. The prototype will be the same except that StringRef is replaced with something that is byte width agnostic. Adding CharWidth argument now reduces the future diff. --- clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp | 4 +- llvm/include/llvm/Analysis/ValueTracking.h| 2 +- llvm/lib/Analysis/ValueTracking.cpp | 7 +- .../AMDGPU/AMDGPUPrintfRuntimeBinding.cpp | 4 +- llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp | 2 +- .../Target/SPIRV/SPIRVPrepareFunctions.cpp| 2 +- .../WebAssembly/WebAssemblyAsmPrinter.cpp | 2 +- .../AggressiveInstCombine.cpp | 12 +- .../lib/Transforms/Utils/AMDGPUEmitPrintf.cpp | 4 +- .../lib/Transforms/Utils/SimplifyLibCalls.cpp | 103 -- 10 files changed, 96 insertions(+), 46 deletions(-) diff --git a/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp b/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp index f09b3b92c4ea0..b7b65634238c4 100644 --- a/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp @@ -226,7 +226,7 @@ void CodeGenFunction::ProcessOrderScopeAMDGCN(Value *Order, Value *Scope, // Some of the atomic builtins take the scope as a string name. StringRef scp; - if (llvm::getConstantStringInfo(Scope, scp)) { + if (llvm::getConstantStringInfo(Scope, scp, /*CharWidth=*/8)) { SSID = getLLVMContext().getOrInsertSyncScopeID(scp); return; } @@ -281,7 +281,7 @@ void CodeGenFunction::AddAMDGPUFenceAddressSpaceMMRA(llvm::Instruction *Inst, for (unsigned K = 2; K < E->getNumArgs(); ++K) { llvm::Value *V = EmitScalarExpr(E->getArg(K)); StringRef AS; -if (llvm::getConstantStringInfo(V, AS)) { +if (llvm::getConstantStringInfo(V, AS, /*CharWidth=*/8)) { MMRAs.push_back({Tag, AS}); // TODO: Delete the resulting unused constant? continue; diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h index 02990a3cb44f7..e6fb3cb9bd044 100644 --- a/llvm/include/llvm/Analysis/ValueTracking.h +++ b/llvm/include/llvm/Analysis/ValueTracking.h @@ -404,7 +404,7 @@ LLVM_ABI bool getConstantDataArrayInfo(const Value *V, /// trailing null characters as well as any other characters that come after /// it. LLVM_ABI bool getConstantStringInfo(const Value *V, StringRef &Str, -bool TrimAtNul = true); +unsigned CharWidth, bool TrimAtNul = true); /// If we can compute the length of the string pointed to by the specified /// pointer, return 'len+1'. If we can't, return 0. diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 858d79b7f095b..ed202b8a1f6e5 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -6457,9 +6457,12 @@ bool llvm::getConstantDataArrayInfo(const Value *V, /// return true. When TrimAtNul is set, Str will contain only the bytes up /// to but not including the first nul. Return false on failure. bool llvm::getConstantStringInfo(const Value *V, StringRef &Str, - bool TrimAtNul) { + unsigned CharWidth, bool TrimAtNul) { + if (CharWidth != CHAR_BIT) +return false; + ConstantDataArraySlice Slice; - if (!getConstantDataArrayInfo(V, Slice, 8)) + if (!getConstantDataArrayInfo(V, Slice, CharWidth)) return false; if (Slice.Array == nullptr) { diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp index 7a2a7fc250e27..471dfbc53274c 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPrintfRuntimeBinding.cpp @@ -121,7 +121,7 @@ static_assert(NonLiteralStr.size() == 3); static StringRef getAsConstantStr(Value *V) { StringRef S; - if (!getConstantStringInfo(V, S)) + if (!getConstantStringInfo(V, S, /*CharWidth=*/8)) S = NonLiteralStr; return S; @@ -154,7 +154,7 @@ bool AMDGPUPrintfRuntimeBindingImpl::lowerPrintfForGpu(Module &M) { Value *Op = CI->getArgOperand(0); StringRef FormatStr; -if (!getConstantStringInfo(Op, FormatStr)) { +if (!getConstantStringInfo(Op, FormatStr, /*CharWidth=*/8)) { V
[llvm-branch-commits] [llvm] [IR] Account for byte width in m_PtrAdd (PR #106540)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106540 >From 161e6baa5bd1b8349d79e4cf1f4d3ce32348502f Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Thu, 29 Aug 2024 00:54:20 +0300 Subject: [PATCH] [IR] Account for byte width in m_PtrAdd The method has few uses yet, so just pass DL argument to it. The change follows m_PtrToIntSameSize, and I don't see a better way of delivering the byte width to the method. --- llvm/include/llvm/IR/PatternMatch.h | 13 ++ llvm/lib/Analysis/InstructionSimplify.cpp | 2 +- .../InstCombineSimplifyDemanded.cpp | 7 ++--- .../InstCombine/InstructionCombining.cpp | 2 +- llvm/unittests/IR/PatternMatch.cpp| 26 ++- 5 files changed, 34 insertions(+), 16 deletions(-) diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index ed9b83d5d4361..c5fb399070e02 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -1940,15 +1940,17 @@ struct m_SplatOrPoisonMask { }; template struct PtrAdd_match { + const DataLayout &DL; PointerOpTy PointerOp; OffsetOpTy OffsetOp; - PtrAdd_match(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp) - : PointerOp(PointerOp), OffsetOp(OffsetOp) {} + PtrAdd_match(const DataLayout &DL, const PointerOpTy &PointerOp, + const OffsetOpTy &OffsetOp) + : DL(DL), PointerOp(PointerOp), OffsetOp(OffsetOp) {} template bool match(OpTy *V) const { auto *GEP = dyn_cast(V); -return GEP && GEP->getSourceElementType()->isIntegerTy(8) && +return GEP && GEP->getSourceElementType()->isIntegerTy(DL.getByteWidth()) && PointerOp.match(GEP->getPointerOperand()) && OffsetOp.match(GEP->idx_begin()->get()); } @@ -1990,8 +1992,9 @@ inline auto m_GEP(const OperandTypes &...Ops) { /// Matches GEP with i8 source element type template inline PtrAdd_match -m_PtrAdd(const PointerOpTy &PointerOp, const OffsetOpTy &OffsetOp) { - return PtrAdd_match(PointerOp, OffsetOp); +m_PtrAdd(const DataLayout &DL, const PointerOpTy &PointerOp, + const OffsetOpTy &OffsetOp) { + return PtrAdd_match(DL, PointerOp, OffsetOp); } //===--===// diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 82530e7d5b6c6..f310a5db5aee1 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -5389,7 +5389,7 @@ static Value *simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, // ptrtoint (ptradd (Ptr, X - ptrtoint(Ptr))) -> X Value *Ptr, *X; if (CastOpc == Instruction::PtrToInt && - match(Op, m_PtrAdd(m_Value(Ptr), + match(Op, m_PtrAdd(Q.DL, m_Value(Ptr), m_Sub(m_Value(X), m_PtrToInt(m_Deferred(Ptr) && X->getType() == Ty && Ty == Q.DL.getIndexType(Ptr->getType())) return X; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 0e3436d12702d..cc5b4f3cb63bf 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -991,9 +991,10 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I, Value *InnerPtr; uint64_t GEPIndex; uint64_t PtrMaskImmediate; -if (match(I, m_Intrinsic( - m_PtrAdd(m_Value(InnerPtr), m_ConstantInt(GEPIndex)), - m_ConstantInt(PtrMaskImmediate { +if (match(I, + m_Intrinsic( + m_PtrAdd(DL, m_Value(InnerPtr), m_ConstantInt(GEPIndex)), + m_ConstantInt(PtrMaskImmediate { LHSKnown = computeKnownBits(InnerPtr, I, Depth + 1); if (!LHSKnown.isZero()) { diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 91a1b61ddc483..66358359275d2 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2595,7 +2595,7 @@ static Instruction *canonicalizeGEPOfConstGEPI8(GetElementPtrInst &GEP, auto &DL = IC.getDataLayout(); Value *Base; const APInt *C1; - if (!match(Src, m_PtrAdd(m_Value(Base), m_APInt(C1 + if (!match(Src, m_PtrAdd(DL, m_Value(Base), m_APInt(C1 return nullptr; Value *VarIndex; const APInt *C2; diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp index bb7cc0802b1df..c88c01b9e5541 100644 --- a/llvm/unittests/IR/PatternMatch.cpp +++ b/llvm/unittests/IR/PatternMatch.cpp @@ -2599,26 +2599,40 @@ TEST_F(PatternMatchTest, ConstExpr) { EXPECT_TRUE(match(V, m_ConstantExpr())); } -TEST_F(PatternMatch
[llvm-branch-commits] [llvm] [IRBuilder] Add getByteTy and use it in CreatePtrAdd (PR #106539)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106539 >From 517a87c03b68e0a9392841276fd69dd3c483eb12 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Thu, 22 Aug 2024 15:10:58 +0300 Subject: [PATCH] [IRBuilder] Add getByteTy and use it in CreatePtrAdd The change requires DataLayout instance to be available, which, in turn, requires insertion point to be set. In-tree tests detected only one case when the function was called without setting an insertion point, it was changed to create a constant expression directly. --- llvm/include/llvm/IR/IRBuilder.h | 10 +++-- .../Instrumentation/SanitizerCoverage.cpp | 5 ++--- llvm/unittests/IR/IRBuilderTest.cpp | 22 +++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index 7c600e762a451..b0c60056e740d 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -543,6 +543,12 @@ class IRBuilderBase { // Type creation methods //======// + /// Fetch the type representing a byte. + IntegerType *getByteTy() { +const DataLayout &DL = BB->getDataLayout(); +return Type::getIntNTy(Context, DL.getByteWidth()); + } + /// Fetch the type representing a single bit IntegerType *getInt1Ty() { return Type::getInt1Ty(Context); @@ -2040,12 +2046,12 @@ class IRBuilderBase { Value *CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name = "", GEPNoWrapFlags NW = GEPNoWrapFlags::none()) { -return CreateGEP(getInt8Ty(), Ptr, Offset, Name, NW); +return CreateGEP(getByteTy(), Ptr, Offset, Name, NW); } Value *CreateInBoundsPtrAdd(Value *Ptr, Value *Offset, const Twine &Name = "") { -return CreateGEP(getInt8Ty(), Ptr, Offset, Name, +return CreateGEP(getByteTy(), Ptr, Offset, Name, GEPNoWrapFlags::inBounds()); } diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index 5b8ea1547ca2f..a45b56696f612 100644 --- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -357,14 +357,13 @@ ModuleSanitizerCoverage::CreateSecStartEnd(Module &M, const char *Section, GlobalVariable *SecEnd = new GlobalVariable(M, Ty, false, Linkage, nullptr, getSectionEnd(Section)); SecEnd->setVisibility(GlobalValue::HiddenVisibility); - IRBuilder<> IRB(M.getContext()); if (!TargetTriple.isOSBinFormatCOFF()) return std::make_pair(SecStart, SecEnd); // Account for the fact that on windows-msvc __start_* symbols actually // point to a uint64_t before the start of the array. - auto GEP = - IRB.CreatePtrAdd(SecStart, ConstantInt::get(IntptrTy, sizeof(uint64_t))); + Constant *GEP = ConstantExpr::getGetElementPtr( + Int8Ty, SecStart, ConstantInt::get(IntptrTy, sizeof(uint64_t))); return std::make_pair(GEP, SecEnd); } diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp index 4f2ede3321080..9a0be982b2175 100644 --- a/llvm/unittests/IR/IRBuilderTest.cpp +++ b/llvm/unittests/IR/IRBuilderTest.cpp @@ -525,6 +525,14 @@ TEST_F(IRBuilderTest, DataLayout) { EXPECT_FALSE(M->getDataLayout().isLegalInteger(32)); } +TEST_F(IRBuilderTest, GetByteTy) { + IRBuilder<> Builder(BB); + + EXPECT_TRUE(Builder.getByteTy()->isIntegerTy(8)); + M->setDataLayout("b:32"); + EXPECT_TRUE(Builder.getByteTy()->isIntegerTy(32)); +} + TEST_F(IRBuilderTest, GetIntTy) { IRBuilder<> Builder(BB); IntegerType *Ty1 = Builder.getInt1Ty(); @@ -536,6 +544,20 @@ TEST_F(IRBuilderTest, GetIntTy) { EXPECT_EQ(IntPtrTy, IntegerType::get(Ctx, IntPtrBitSize)); } +TEST_F(IRBuilderTest, CreatePtrAdd) { + IRBuilder<> Builder(BB); + + M->setDataLayout("b:16-p:32:32"); + Value *V = Builder.CreatePtrAdd(GV, ConstantInt::get(Ctx, APInt(32, 42))); + ASSERT_TRUE(isa(V)); + EXPECT_TRUE(cast(V)->getResultElementType()->isIntegerTy(16)); + + M->setDataLayout("b:32-p:64:32"); + V = Builder.CreateInBoundsPtrAdd(GV, ConstantInt::get(Ctx, APInt(64, 42))); + ASSERT_TRUE(isa(V)); + EXPECT_TRUE(cast(V)->getResultElementType()->isIntegerTy(32)); +} + TEST_F(IRBuilderTest, UnaryOperators) { IRBuilder Builder(BB); Value *V = Builder.CreateLoad(GV->getValueType(), GV); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [ValueTracking] Make isBytewiseValue byte width agnostic (PR #106538)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106538 >From 81781bc2aa7360f50688e24b361ef768d4d6f961 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Fri, 2 Aug 2024 13:14:49 +0300 Subject: [PATCH] [ValueTracking] Make isBytewiseValue byte width agnostic This is a simple change to show how easy it can be to support unusual byte widths in the middle end. --- llvm/lib/Analysis/ValueTracking.cpp | 30 +++-- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 21f844c4d2f45..858d79b7f095b 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -6068,21 +6068,22 @@ bool llvm::canIgnoreSignBitOfNaN(const Use &U) { } Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { + unsigned ByteWidth = DL.getByteWidth(); // All byte-wide stores are splatable, even of arbitrary variables. - if (V->getType()->isIntegerTy(8)) + if (V->getType()->isIntegerTy(ByteWidth)) return V; LLVMContext &Ctx = V->getContext(); // Undef don't care. - auto *UndefInt8 = UndefValue::get(Type::getInt8Ty(Ctx)); + auto *UndefByte = UndefValue::get(Type::getIntNTy(Ctx, ByteWidth)); if (isa(V)) -return UndefInt8; +return UndefByte; // Return poison for zero-sized type. if (DL.getTypeStoreSize(V->getType()).isZero()) -return PoisonValue::get(Type::getInt8Ty(Ctx)); +return PoisonValue::get(Type::getIntNTy(Ctx, ByteWidth)); Constant *C = dyn_cast(V); if (!C) { @@ -6097,7 +6098,7 @@ Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { // Handle 'null' ConstantArrayZero etc. if (C->isNullValue()) -return Constant::getNullValue(Type::getInt8Ty(Ctx)); +return Constant::getNullValue(Type::getIntNTy(Ctx, ByteWidth)); // Constant floating-point values can be handled as integer values if the // corresponding integer value is "byteable". An important case is 0.0. @@ -6114,13 +6115,14 @@ Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { : nullptr; } - // We can handle constant integers that are multiple of 8 bits. + // We can handle constant integers that are multiple of the byte width. if (ConstantInt *CI = dyn_cast(C)) { -if (CI->getBitWidth() % 8 == 0) { - assert(CI->getBitWidth() > 8 && "8 bits should be handled above!"); - if (!CI->getValue().isSplat(8)) +if (CI->getBitWidth() % ByteWidth == 0) { + assert(CI->getBitWidth() > ByteWidth && + "single byte should be handled above!"); + if (!CI->getValue().isSplat(ByteWidth)) return nullptr; - return ConstantInt::get(Ctx, CI->getValue().trunc(8)); + return ConstantInt::get(Ctx, CI->getValue().trunc(ByteWidth)); } } @@ -6140,15 +6142,15 @@ Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { return LHS; if (!LHS || !RHS) return nullptr; -if (LHS == UndefInt8) +if (LHS == UndefByte) return RHS; -if (RHS == UndefInt8) +if (RHS == UndefByte) return LHS; return nullptr; }; if (ConstantDataSequential *CA = dyn_cast(C)) { -Value *Val = UndefInt8; +Value *Val = UndefByte; for (uint64_t I = 0, E = CA->getNumElements(); I != E; ++I) if (!(Val = Merge(Val, isBytewiseValue(CA->getElementAsConstant(I), DL return nullptr; @@ -6156,7 +6158,7 @@ Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) { } if (isa(C)) { -Value *Val = UndefInt8; +Value *Val = UndefByte; for (Value *Op : C->operands()) if (!(Val = Merge(Val, isBytewiseValue(Op, DL return nullptr; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [mlir] [IR] Make @llvm.memset prototype byte width dependent (PR #106537)
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/106537 >From 83efc1aa133fb2e52e81ae4319c978859da61911 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Thu, 1 Aug 2024 23:47:25 +0300 Subject: [PATCH] [IR] Make @llvm.memset prototype byte width dependent This patch changes the type of the value argument of @llvm.memset and similar intrinsics from i8 to iN, where N is the byte width specified in data layout string. Note that the argument still has fixed type (not overloaded), but type checker will complain if the type does not match the byte width. Ideally, the type of the argument would be dependent on the address space of the pointer argument. It is easy to do this (and I did it downstream as a PoC), but since data layout string doesn't currently allow different byte widths for different address spaces, I refrained from doing it now. --- llvm/include/llvm-c/Core.h| 2 +- llvm/include/llvm/IR/Intrinsics.h | 14 +++-- llvm/include/llvm/IR/Intrinsics.td| 13 ++-- llvm/lib/AsmParser/LLParser.cpp | 4 +- llvm/lib/IR/AutoUpgrade.cpp | 4 +- llvm/lib/IR/Core.cpp | 4 +- llvm/lib/IR/Function.cpp | 4 +- llvm/lib/IR/IRBuilder.cpp | 2 +- llvm/lib/IR/Intrinsics.cpp| 61 +++ llvm/lib/IR/Verifier.cpp | 2 +- .../NumericalStabilitySanitizer.cpp | 2 +- .../LLVMIR/LLVMToLLVMIRTranslation.cpp| 4 +- 12 files changed, 69 insertions(+), 47 deletions(-) diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index d645646289025..4ecc657837910 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -2930,7 +2930,7 @@ LLVM_C_ABI LLVMValueRef LLVMGetIntrinsicDeclaration(LLVMModuleRef Mod, * * @see llvm::Intrinsic::getType() */ -LLVM_C_ABI LLVMTypeRef LLVMIntrinsicGetType(LLVMContextRef Ctx, unsigned ID, +LLVM_C_ABI LLVMTypeRef LLVMIntrinsicGetType(LLVMModuleRef Mod, unsigned ID, LLVMTypeRef *ParamTypes, size_t ParamCount); diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h index 156805293367b..896c952c95c14 100644 --- a/llvm/include/llvm/IR/Intrinsics.h +++ b/llvm/include/llvm/IR/Intrinsics.h @@ -23,6 +23,7 @@ namespace llvm { +class DataLayout; class Type; class FunctionType; class Function; @@ -75,8 +76,7 @@ namespace Intrinsic { LLVM_ABI std::string getNameNoUnnamedTypes(ID Id, ArrayRef Tys); /// Return the function type for an intrinsic. - LLVM_ABI FunctionType *getType(LLVMContext &Context, ID id, - ArrayRef Tys = {}); + LLVM_ABI FunctionType *getType(Module *M, ID id, ArrayRef Tys = {}); /// Returns true if the intrinsic can be overloaded. LLVM_ABI bool isOverloaded(ID id); @@ -141,6 +141,7 @@ namespace Intrinsic { struct IITDescriptor { enum IITDescriptorKind { Void, + Byte, VarArg, MMX, Token, @@ -253,9 +254,9 @@ namespace Intrinsic { /// /// Returns false if the given type matches with the constraints, true /// otherwise. - LLVM_ABI MatchIntrinsicTypesResult - matchIntrinsicSignature(FunctionType *FTy, ArrayRef &Infos, - SmallVectorImpl &ArgTys); + LLVM_ABI MatchIntrinsicTypesResult matchIntrinsicSignature( + const DataLayout &DL, FunctionType *FTy, ArrayRef &Infos, + SmallVectorImpl &ArgTys); /// Verify if the intrinsic has variable arguments. This method is intended to /// be called after all the fixed arguments have been matched first. @@ -270,7 +271,8 @@ namespace Intrinsic { /// /// Returns false if the given ID and function type combination is not a /// valid intrinsic call. - LLVM_ABI bool getIntrinsicSignature(Intrinsic::ID, FunctionType *FT, + LLVM_ABI bool getIntrinsicSignature(const DataLayout &DL, Intrinsic::ID, + FunctionType *FT, SmallVectorImpl &ArgTys); /// Same as previous, but accepts a Function instead of ID and FunctionType. diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index bd6f94ac1286c..438910fd2aef5 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -308,6 +308,7 @@ def IIT_V1 : IIT_Vec<1, 28>; def IIT_VARARG : IIT_VT; def IIT_ONE_NTH_ELTS_VEC_ARG : IIT_Base<30>; def IIT_SAME_VEC_WIDTH_ARG : IIT_Base<31>; +def IIT_BYTE : IIT_Base<32>; def IIT_VEC_OF_ANYPTRS_TO_ELT : IIT_Base<34>; def IIT_I128 : IIT_Int<128, 35>; def IIT_V512 : IIT_Vec<512, 36>; @@ -392,6 +393,10 @@ class LLVMType { !foreach(iit, IITs, iit.Number)); } +class LLVMByteType : LLVMType { + let Sig = [IIT_BYTE.Number]; +} + class LLVMAnyType : LLVMType { let
[llvm-branch-commits] [llvm] [DA] Add check for base pointer invariance (PR #148241)
https://github.com/kasuga-fj converted_to_draft https://github.com/llvm/llvm-project/pull/148241 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AArch64] Prepare for split ZPR and PPR area allocation (NFCI) (PR #142391)
@@ -4308,26 +4398,33 @@ static int64_t determineSVEStackObjectOffsets(MachineFrameInfo &MFI, "reference."); #endif - auto Assign = [&MFI](int FI, int64_t Offset) { + auto StackForObject = [&](int FI, uint64_t &ZPRStackTop, +uint64_t &PPRStackTop) -> uint64_t & { +return MFI.getStackID(FI) == TargetStackID::ScalableVector ? ZPRStackTop + : PPRStackTop; + }; + + auto Assign = [&MFI, AssignOffsets](int FI, int64_t Offset) { +if (AssignOffsets == AssignObjectOffsets::No) + return; LLVM_DEBUG(dbgs() << "alloc FI(" << FI << ") at SP[" << Offset << "]\n"); MFI.setObjectOffset(FI, Offset); }; - int64_t Offset = 0; - // Then process all callee saved slots. + int MinCSFrameIndex, MaxCSFrameIndex; if (getSVECalleeSaveSlotRange(MFI, MinCSFrameIndex, MaxCSFrameIndex)) { -// Assign offsets to the callee save slots. -for (int I = MinCSFrameIndex; I <= MaxCSFrameIndex; ++I) { - Offset += MFI.getObjectSize(I); - Offset = alignTo(Offset, MFI.getObjectAlign(I)); - if (AssignOffsets) -Assign(I, -Offset); +for (int FI = MinCSFrameIndex; FI <= MaxCSFrameIndex; ++FI) { + uint64_t &StackTop = StackForObject(FI, ZPRStackTop, PPRStackTop); + StackTop += MFI.getObjectSize(FI); + StackTop = alignTo(StackTop, MFI.getObjectAlign(FI)); + Assign(FI, -int64_t(StackTop)); MacDue wrote: I've added the assert and moved common logic into `AllocateObject` (what used to be `Assign`). https://github.com/llvm/llvm-project/pull/142391 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [CodeGen][NPM] Port ProcessImplicitDefs to NPM (PR #148110)
https://github.com/optimisan edited https://github.com/llvm/llvm-project/pull/148110 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [CodeGen][NPM] Port ProcessImplicitDefs to NPM (PR #148110)
https://github.com/optimisan approved this pull request. https://github.com/llvm/llvm-project/pull/148110 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AArch64] Prepare for split ZPR and PPR area allocation (NFCI) (PR #142391)
https://github.com/MacDue updated https://github.com/llvm/llvm-project/pull/142391 >From 8664a890ef0567b92b82fd8eee8b69914fac678b Mon Sep 17 00:00:00 2001 From: Benjamin Maxwell Date: Thu, 8 May 2025 17:38:27 + Subject: [PATCH 1/8] [AArch64] Prepare for split ZPR and PPR area allocation (NFCI) This patch attempts to refactor AArch64FrameLowering to allow the size of the ZPR and PPR areas to be calculated separately. This will be used by a subsequent patch to support allocating ZPRs and PPRs to separate areas. This patch should be an NFC and is split out to make later functional changes easier to spot. --- .../Target/AArch64/AArch64FrameLowering.cpp | 306 -- .../lib/Target/AArch64/AArch64FrameLowering.h | 12 +- .../AArch64/AArch64MachineFunctionInfo.h | 61 ++-- .../Target/AArch64/AArch64RegisterInfo.cpp| 7 +- 4 files changed, 257 insertions(+), 129 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 409a21a37810f..054347fef4622 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -330,10 +330,13 @@ static int64_t getArgumentStackToRestore(MachineFunction &MF, static bool produceCompactUnwindFrame(MachineFunction &MF); static bool needsWinCFI(const MachineFunction &MF); +static StackOffset getZPRStackSize(const MachineFunction &MF); +static StackOffset getPPRStackSize(const MachineFunction &MF); static StackOffset getSVEStackSize(const MachineFunction &MF); static Register findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB, bool HasCall = false); static bool requiresSaveVG(const MachineFunction &MF); +static bool hasSVEStackSize(const MachineFunction &MF); // Conservatively, returns true if the function is likely to have SVE vectors // on the stack. This function is safe to be called before callee-saves or @@ -493,10 +496,36 @@ static unsigned getFixedObjectSize(const MachineFunction &MF, } } -/// Returns the size of the entire SVE stackframe (calleesaves + spills). +static unsigned getStackHazardSize(const MachineFunction &MF) { + return MF.getSubtarget().getStreamingHazardSize(); +} + +/// Returns the size of the entire ZPR stackframe (calleesaves + spills). +static StackOffset getZPRStackSize(const MachineFunction &MF) { + const AArch64FunctionInfo *AFI = MF.getInfo(); + return StackOffset::getScalable(AFI->getStackSizeZPR()); +} + +/// Returns the size of the entire PPR stackframe (calleesaves + spills). +static StackOffset getPPRStackSize(const MachineFunction &MF) { + const AArch64FunctionInfo *AFI = MF.getInfo(); + return StackOffset::getScalable(AFI->getStackSizePPR()); +} + +/// Returns the size of the entire SVE stackframe (PPRs + ZPRs). static StackOffset getSVEStackSize(const MachineFunction &MF) { + return getZPRStackSize(MF) + getPPRStackSize(MF); +} + +static bool hasSVEStackSize(const MachineFunction &MF) { const AArch64FunctionInfo *AFI = MF.getInfo(); - return StackOffset::getScalable((int64_t)AFI->getStackSizeSVE()); + return AFI->getStackSizeZPR() > 0 || AFI->getStackSizePPR() > 0; +} + +/// Returns true if PPRs are spilled as ZPRs. +static bool arePPRsSpilledAsZPR(const MachineFunction &MF) { + return MF.getSubtarget().getRegisterInfo()->getSpillSize( + AArch64::PPRRegClass) == 16; } bool AArch64FrameLowering::canUseRedZone(const MachineFunction &MF) const { @@ -524,7 +553,7 @@ bool AArch64FrameLowering::canUseRedZone(const MachineFunction &MF) const { !Subtarget.hasSVE(); return !(MFI.hasCalls() || hasFP(MF) || NumBytes > RedZoneSize || - getSVEStackSize(MF) || LowerQRegCopyThroughMem); + hasSVEStackSize(MF) || LowerQRegCopyThroughMem); } /// hasFPImpl - Return true if the specified function should have a dedicated @@ -1224,7 +1253,7 @@ bool AArch64FrameLowering::shouldCombineCSRLocalStackBump( // When there is an SVE area on the stack, always allocate the // callee-saves and spills/locals separately. - if (getSVEStackSize(MF)) + if (hasSVEStackSize(MF)) return false; return true; @@ -1668,25 +1697,19 @@ static bool isTargetWindows(const MachineFunction &MF) { return MF.getSubtarget().isTargetWindows(); } -static unsigned getStackHazardSize(const MachineFunction &MF) { - return MF.getSubtarget().getStreamingHazardSize(); -} - // Convenience function to determine whether I is an SVE callee save. -static bool IsSVECalleeSave(MachineBasicBlock::iterator I) { +static bool IsZPRCalleeSave(MachineBasicBlock::iterator I) { switch (I->getOpcode()) { default: return false; - case AArch64::PTRUE_C_B: case AArch64::LD1B_2Z_IMM: case AArch64::ST1B_2Z_IMM: case AArch64::STR_ZXI: - case AArch64::STR_PXI: case AArch64::LDR_ZXI: - case AArch64::LDR_PXI: - case AArch64::PTRUE_B: case AArch64
[llvm-branch-commits] [llvm] [CodeGen][NPM] Register Function Passes (PR #148109)
https://github.com/optimisan approved this pull request. https://github.com/llvm/llvm-project/pull/148109 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [CodeGen][NPM] Register Function Passes (PR #148109)
https://github.com/optimisan edited https://github.com/llvm/llvm-project/pull/148109 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [CodeGen][NPM] Read TargetMachine's EnableIPRA option (PR #148108)
https://github.com/optimisan approved this pull request. https://github.com/llvm/llvm-project/pull/148108 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [CodeGen][NPM] Read TargetMachine's EnableIPRA option (PR #148108)
https://github.com/optimisan edited https://github.com/llvm/llvm-project/pull/148108 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [CodeGen][NPM] VirtRegRewriter: Set VirtReg flag (PR #148107)
https://github.com/optimisan edited https://github.com/llvm/llvm-project/pull/148107 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [CodeGen][NPM] VirtRegRewriter: Set VirtReg flag (PR #148107)
https://github.com/optimisan approved this pull request. https://github.com/llvm/llvm-project/pull/148107 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] ELF: Introduce R_AARCH64_FUNCINIT64 relocation type. (PR #133531)
@@ -0,0 +1,19 @@ +# REQUIRES: aarch64 + +# RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o +# RUN: ld.lld %t.o -o %t +# RUN: llvm-readelf -s -r %t | FileCheck %s +# RUN: ld.lld %t.o -o %t -pie +# RUN: llvm-readelf -s -r %t | FileCheck %s +# RUN: not ld.lld %t.o -o %t -shared 2>&1 | FileCheck --check-prefix=ERR %s + +.data +# CHECK: R_AARCH64_IRELATIVE [[FOO:[0-9a-f]*]] +# ERR: relocation R_AARCH64_FUNCINIT64 cannot be used against preemptible symbol 'foo' +.8byte foo@FUNCINIT smithp35 wrote: Although not this patch, MaskRay is proposing that we use a different syntax for relocation specifiers to avoid ambiguity with the addend: https://maskray.me/blog/2025-03-16-relocation-generation-in-assemblers I'm proposing that aarch64 ELF follows this for data relocation specifiers (first one in https://github.com/ARM-software/abi-aa/pull/330/files#diff-c74a0dce6771ac7b499e84c140122aaa972bd9d63aed84863e675ecc9b4b2c32R659) I'm assuming that we could migrate to this syntax at a later date if needed. https://github.com/llvm/llvm-project/pull/133531 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] ELF: Introduce R_AARCH64_FUNCINIT64 relocation type. (PR #133531)
https://github.com/smithp35 commented: I don't have any more significant comments and no objections to the patch. Going back to my previous comments I was most concerned when the target was an ifunc symbol and that is now not supported. https://github.com/llvm/llvm-project/pull/133531 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [lld] ELF: Introduce R_AARCH64_FUNCINIT64 relocation type. (PR #133531)
https://github.com/smithp35 edited https://github.com/llvm/llvm-project/pull/133531 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] ELF: Introduce R_AARCH64_PATCHINST relocation type. (PR #133534)
@@ -0,0 +1,41 @@ +# RUN: rm -rf %t && split-file %s %t +# RUN: llvm-mc -filetype=obj -triple=aarch64 %t/use.s -o %t/use-le.o +# RUN: llvm-mc -filetype=obj -triple=aarch64 %t/def.s -o %t/def-le.o + +## Deactivation symbol used without being defined: instruction emitted as usual. +# RUN: ld.lld -o %t/undef-le %t/use-le.o +# RUN: llvm-objdump -d %t/undef-le | FileCheck --check-prefix=UNDEF %s + +## Deactivation symbol defined: instructions overwritten with NOPs. +# RUN: ld.lld -o %t/def-le %t/use-le.o %t/def-le.o +# RUN: llvm-objdump -d %t/def-le | FileCheck --check-prefix=DEF %s + +## Behavior unchanged by endianness: relocation always written as little endian. +# RUN: llvm-mc -filetype=obj -triple=aarch64_be %t/use.s -o %t/use-be.o +# RUN: llvm-mc -filetype=obj -triple=aarch64_be %t/def.s -o %t/def-be.o +# RUN: ld.lld -o %t/undef-be %t/use-be.o +# RUN: llvm-objdump -d %t/undef-be | FileCheck --check-prefix=UNDEF %s +# RUN: ld.lld -o %t/def-be %t/use-be.o %t/def-be.o +# RUN: llvm-objdump -d %t/def-be | FileCheck --check-prefix=DEF %s + +#--- use.s +.weak ds +# This instruction has a single relocation: the DS relocation. +# UNDEF: add x0, x1, x2 +# DEF: nop +.reloc ., R_AARCH64_PATCHINST, ds +add x0, x1, x2 +# This instruction has two relocations: the DS relocation and the JUMP26 to f1. +# Make sure that the DS relocation takes precedence. +.reloc ., R_AARCH64_PATCHINST, ds smithp35 wrote: Could be worth a test with emit-relocs to show both relocations coming out. Thinking of Bolt, which relies on emit-relocs, I expect that it would just ignore the R_AARCH_PATCHINST relocations on their own as it wouldn't know how to recreate the original value [1]. It would have to discard any relocation at the same location. We're hoping to create a binary analysis ABI supplement soon to document conventions that binary analysis tools are using. First step https://github.com/ARM-software/abi-aa/pull/333 [1] In theory if we did want to let Bolt reverse a patch, the emit-relocs output could give the reverse patch. https://github.com/llvm/llvm-project/pull/133534 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] ELF: Introduce R_AARCH64_PATCHINST relocation type. (PR #133534)
@@ -137,6 +137,7 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s, switch (type) { case R_AARCH64_ABS16: case R_AARCH64_ABS32: + case R_AARCH64_PATCHINST: smithp35 wrote: If the relocation is used as described in the RFC, with the target symbol absolute all looks well. If a non ABS symbol is used in a position independent context I think you'll get a recompile with PIC error message. If not position independent then I think the relocation will pass through and give a likely unpredictable value to patch the instruction. Could it be worth putting some checking (likely in Relocation.cpp) to make sure the target symbol is SHN_ABS? A related question is whether non-zero addends should be supported? For most instructions the addend doesn't make logical sense. There could be some instructions where the immediate field is in the right place to make it work, but I think these cases may not be worth supporting. An alternative formulation for RELA is to completely ignore the symbol value and just use the bottom 32-bits of the addend field. That would give the object producer that defines the relocations more control over what is patched in. Not got a strong opinion on whether that is better though. https://github.com/llvm/llvm-project/pull/133534 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AArch64] Prepare for split ZPR and PPR area allocation (NFCI) (PR #142391)
@@ -4308,26 +4398,33 @@ static int64_t determineSVEStackObjectOffsets(MachineFrameInfo &MFI, "reference."); #endif - auto Assign = [&MFI](int FI, int64_t Offset) { + auto StackForObject = [&](int FI, uint64_t &ZPRStackTop, +uint64_t &PPRStackTop) -> uint64_t & { +return MFI.getStackID(FI) == TargetStackID::ScalableVector ? ZPRStackTop + : PPRStackTop; + }; + + auto Assign = [&MFI, AssignOffsets](int FI, int64_t Offset) { +if (AssignOffsets == AssignObjectOffsets::No) + return; LLVM_DEBUG(dbgs() << "alloc FI(" << FI << ") at SP[" << Offset << "]\n"); MFI.setObjectOffset(FI, Offset); }; - int64_t Offset = 0; - // Then process all callee saved slots. + int MinCSFrameIndex, MaxCSFrameIndex; if (getSVECalleeSaveSlotRange(MFI, MinCSFrameIndex, MaxCSFrameIndex)) { -// Assign offsets to the callee save slots. -for (int I = MinCSFrameIndex; I <= MaxCSFrameIndex; ++I) { - Offset += MFI.getObjectSize(I); - Offset = alignTo(Offset, MFI.getObjectAlign(I)); - if (AssignOffsets) -Assign(I, -Offset); +for (int FI = MinCSFrameIndex; FI <= MaxCSFrameIndex; ++FI) { + uint64_t &StackTop = StackForObject(FI, ZPRStackTop, PPRStackTop); + StackTop += MFI.getObjectSize(FI); + StackTop = alignTo(StackTop, MFI.getObjectAlign(FI)); + Assign(FI, -int64_t(StackTop)); MacDue wrote: Sure, I'm not sure LLVM would handle 9,223 petabytesstacks very well :laughing: https://github.com/llvm/llvm-project/pull/142391 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AArch64] Prepare for split ZPR and PPR area allocation (NFCI) (PR #142391)
https://github.com/MacDue edited https://github.com/llvm/llvm-project/pull/142391 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AArch64] Prepare for split ZPR and PPR area allocation (NFCI) (PR #142391)
@@ -4308,26 +4398,33 @@ static int64_t determineSVEStackObjectOffsets(MachineFrameInfo &MFI, "reference."); #endif - auto Assign = [&MFI](int FI, int64_t Offset) { + auto StackForObject = [&](int FI, uint64_t &ZPRStackTop, +uint64_t &PPRStackTop) -> uint64_t & { +return MFI.getStackID(FI) == TargetStackID::ScalableVector ? ZPRStackTop + : PPRStackTop; + }; + + auto Assign = [&MFI, AssignOffsets](int FI, int64_t Offset) { +if (AssignOffsets == AssignObjectOffsets::No) + return; LLVM_DEBUG(dbgs() << "alloc FI(" << FI << ") at SP[" << Offset << "]\n"); MFI.setObjectOffset(FI, Offset); }; - int64_t Offset = 0; - // Then process all callee saved slots. + int MinCSFrameIndex, MaxCSFrameIndex; if (getSVECalleeSaveSlotRange(MFI, MinCSFrameIndex, MaxCSFrameIndex)) { -// Assign offsets to the callee save slots. -for (int I = MinCSFrameIndex; I <= MaxCSFrameIndex; ++I) { - Offset += MFI.getObjectSize(I); - Offset = alignTo(Offset, MFI.getObjectAlign(I)); - if (AssignOffsets) -Assign(I, -Offset); +for (int FI = MinCSFrameIndex; FI <= MaxCSFrameIndex; ++FI) { + uint64_t &StackTop = StackForObject(FI, ZPRStackTop, PPRStackTop); + StackTop += MFI.getObjectSize(FI); + StackTop = alignTo(StackTop, MFI.getObjectAlign(FI)); + Assign(FI, -int64_t(StackTop)); sdesmalen-arm wrote: nit: maybe add an assert that `int64_t(StackTop) == StackTop` in case of insanely big stacks? or move this into the `Assign` function so not to have to add that twice. https://github.com/llvm/llvm-project/pull/142391 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AArch64] Prepare for split ZPR and PPR area allocation (NFCI) (PR #142391)
@@ -4042,8 +4124,11 @@ void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF, }); // If any callee-saved registers are used, the frame cannot be eliminated. + auto [ZPRLocalStackSize, PPRLocalStackSize] = + determineSVEStackSizes(MF, AssignObjectOffsets::No); + int64_t SVELocals = ZPRLocalStackSize + PPRLocalStackSize; sdesmalen-arm wrote: ```suggestion uint64_t SVELocals = ZPRLocalStackSize + PPRLocalStackSize; ``` (same for `SVEStackSize` below) https://github.com/llvm/llvm-project/pull/142391 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AArch64] Prepare for split ZPR and PPR area allocation (NFCI) (PR #142391)
https://github.com/sdesmalen-arm edited https://github.com/llvm/llvm-project/pull/142391 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AArch64] Prepare for split ZPR and PPR area allocation (NFCI) (PR #142391)
https://github.com/sdesmalen-arm approved this pull request. LGTM with nits addressed. https://github.com/llvm/llvm-project/pull/142391 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [CIR] Upstream ComplexImagPtrOp for ComplexType (PR #144236)
@@ -1775,6 +1775,44 @@ OpFoldResult cir::ComplexCreateOp::fold(FoldAdaptor adaptor) { return cir::ConstComplexAttr::get(realAttr, imagAttr); } +//===--===// xlauko wrote: These are copy/paste. Can you extract one common implementation. https://github.com/llvm/llvm-project/pull/144236 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [CIR] Upstream ComplexImagPtrOp for ComplexType (PR #144236)
@@ -2385,4 +2385,62 @@ def ComplexCreateOp : CIR_Op<"complex.create", [Pure, SameTypeOperands]> { let hasFolder = 1; } +//===--===// +// ComplexRealPtrOp +//===--===// + +def ComplexRealPtrOp : CIR_Op<"complex.real_ptr", [Pure]> { + let summary = "Derive a pointer to the real part of a complex value"; + let description = [{ +`cir.complex.real_ptr` operation takes a pointer operand that points to a +complex value of type `!cir.complex` and yields a pointer to the real part +of the operand. + +Example: + +```mlir +%1 = cir.complex.real_ptr %0 : !cir.ptr> -> !cir.ptr +``` + }]; + + let results = (outs CIR_PtrToIntOrFloatType:$result); + let arguments = (ins CIR_PtrToComplexType:$operand); + + let assemblyFormat = [{ +$operand `:` +qualified(type($operand)) `->` qualified(type($result)) attr-dict + }]; + + let hasVerifier = 1; +} + +//===--===// +// ComplexImagPtrOp +//===--===// + +def ComplexImagPtrOp : CIR_Op<"complex.imag_ptr", [Pure]> { + let summary = "Derive a pointer to the imaginary part of a complex value"; + let description = [{ +`cir.complex.imag_ptr` operation takes a pointer operand that points to a +complex value of type `!cir.complex` and yields a pointer to the imaginary +part of the operand. + +Example: + +```mlir +%1 = cir.complex.imag_ptr %0 : !cir.ptr> -> !cir.ptr xlauko wrote: fix to 80 cols https://github.com/llvm/llvm-project/pull/144236 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [CIR] Upstream ComplexImagPtrOp for ComplexType (PR #144236)
@@ -1775,6 +1775,44 @@ OpFoldResult cir::ComplexCreateOp::fold(FoldAdaptor adaptor) { return cir::ConstComplexAttr::get(realAttr, imagAttr); } +//===--===// +// ComplexRealPtrOp +//===--===// + +LogicalResult cir::ComplexRealPtrOp::verify() { + mlir::Type resultPointeeTy = getType().getPointee(); + cir::PointerType operandPtrTy = getOperand().getType(); + auto operandPointeeTy = + mlir::cast(operandPtrTy.getPointee()); + + if (resultPointeeTy != operandPointeeTy.getElementType()) { +emitOpError() +<< "cir.complex.real_ptr result type does not match operand type"; +return failure(); + } + + return success(); +} + +//===--===// +// ComplexImagPtrOp +//===--===// + +LogicalResult cir::ComplexImagPtrOp::verify() { + mlir::Type resultPointeeTy = getType().getPointee(); + cir::PointerType operandPtrTy = getOperand().getType(); + auto operandPointeeTy = + mlir::cast(operandPtrTy.getPointee()); + + if (resultPointeeTy != operandPointeeTy.getElementType()) { +emitOpError() +<< "cir.complex.imag_ptr result type does not match operand type"; +return failure(); xlauko wrote: ```suggestion return emitOpError() << "cir.complex.imag_ptr result type does not match operand type"; ``` https://github.com/llvm/llvm-project/pull/144236 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [CIR] Upstream ComplexImagPtrOp for ComplexType (PR #144236)
@@ -1775,6 +1775,44 @@ OpFoldResult cir::ComplexCreateOp::fold(FoldAdaptor adaptor) { return cir::ConstComplexAttr::get(realAttr, imagAttr); } +//===--===// +// ComplexRealPtrOp +//===--===// + +LogicalResult cir::ComplexRealPtrOp::verify() { + mlir::Type resultPointeeTy = getType().getPointee(); + cir::PointerType operandPtrTy = getOperand().getType(); + auto operandPointeeTy = + mlir::cast(operandPtrTy.getPointee()); + + if (resultPointeeTy != operandPointeeTy.getElementType()) { +emitOpError() +<< "cir.complex.real_ptr result type does not match operand type"; +return failure(); xlauko wrote: ```suggestion return emitOpError() << "cir.complex.real_ptr result type does not match operand type"; ``` https://github.com/llvm/llvm-project/pull/144236 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [Offload] Add global variable address/size queries (PR #147972)
https://github.com/RossBrunton updated https://github.com/llvm/llvm-project/pull/147972 >From 77a4183117cd259584c1bb4136aa27dd2b9548b0 Mon Sep 17 00:00:00 2001 From: Ross Brunton Date: Thu, 10 Jul 2025 15:34:17 +0100 Subject: [PATCH] [Offload] Add global variable address/size queries Add two new symbol info types for getting the bounds of a global variable. As well as a number of tests for reading/writing to it. --- offload/liboffload/API/Symbol.td | 4 +- offload/liboffload/src/OffloadImpl.cpp| 19 offload/tools/offload-tblgen/PrintGen.cpp | 8 +- .../unittests/OffloadAPI/memory/olMemcpy.cpp | 105 ++ .../OffloadAPI/symbol/olGetSymbolInfo.cpp | 28 + .../OffloadAPI/symbol/olGetSymbolInfoSize.cpp | 14 +++ 6 files changed, 175 insertions(+), 3 deletions(-) diff --git a/offload/liboffload/API/Symbol.td b/offload/liboffload/API/Symbol.td index 9317c71df1f10..2e94d703809e7 100644 --- a/offload/liboffload/API/Symbol.td +++ b/offload/liboffload/API/Symbol.td @@ -39,7 +39,9 @@ def : Enum { let desc = "Supported symbol info."; let is_typed = 1; let etors = [ -TaggedEtor<"KIND", "ol_symbol_kind_t", "The kind of this symbol."> +TaggedEtor<"KIND", "ol_symbol_kind_t", "The kind of this symbol.">, +TaggedEtor<"GLOBAL_VARIABLE_ADDRESS", "void *", "The address in memory for this global variable.">, +TaggedEtor<"GLOBAL_VARIABLE_SIZE", "size_t", "The size in bytes for this global variable.">, ]; } diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp index 6d98c33ffb8da..17a2b00cb7140 100644 --- a/offload/liboffload/src/OffloadImpl.cpp +++ b/offload/liboffload/src/OffloadImpl.cpp @@ -753,9 +753,28 @@ Error olGetSymbolInfoImplDetail(ol_symbol_handle_t Symbol, void *PropValue, size_t *PropSizeRet) { InfoWriter Info(PropSize, PropValue, PropSizeRet); + auto CheckKind = [&](ol_symbol_kind_t Required) { +if (Symbol->Kind != Required) { + std::string ErrBuffer; + llvm::raw_string_ostream(ErrBuffer) + << PropName << ": Expected a symbol of Kind " << Required + << " but given a symbol of Kind " << Symbol->Kind; + return Plugin::error(ErrorCode::SYMBOL_KIND, ErrBuffer.c_str()); +} +return Plugin::success(); + }; + switch (PropName) { case OL_SYMBOL_INFO_KIND: return Info.write(Symbol->Kind); + case OL_SYMBOL_INFO_GLOBAL_VARIABLE_ADDRESS: +if (auto Err = CheckKind(OL_SYMBOL_KIND_GLOBAL_VARIABLE)) + return Err; +return Info.write(std::get(Symbol->PluginImpl).getPtr()); + case OL_SYMBOL_INFO_GLOBAL_VARIABLE_SIZE: +if (auto Err = CheckKind(OL_SYMBOL_KIND_GLOBAL_VARIABLE)) + return Err; +return Info.write(std::get(Symbol->PluginImpl).getSize()); default: return createOffloadError(ErrorCode::INVALID_ENUMERATION, "olGetSymbolInfo enum '%i' is invalid", PropName); diff --git a/offload/tools/offload-tblgen/PrintGen.cpp b/offload/tools/offload-tblgen/PrintGen.cpp index d1189688a90a3..89d7c820426cf 100644 --- a/offload/tools/offload-tblgen/PrintGen.cpp +++ b/offload/tools/offload-tblgen/PrintGen.cpp @@ -74,8 +74,12 @@ inline void printTagged(llvm::raw_ostream &os, const void *ptr, {0} value, size_ if (Type == "char[]") { OS << formatv(TAB_2 "printPtr(os, (const char*) ptr);\n"); } else { - OS << formatv(TAB_2 "const {0} * const tptr = (const {0} * const)ptr;\n", -Type); + if (Type == "void *") +OS << formatv(TAB_2 "void * const * const tptr = (void * " +"const * const)ptr;\n"); + else +OS << formatv( +TAB_2 "const {0} * const tptr = (const {0} * const)ptr;\n", Type); // TODO: Handle other cases here OS << TAB_2 "os << (const void *)tptr << \" (\";\n"; if (Type.ends_with("*")) { diff --git a/offload/unittests/OffloadAPI/memory/olMemcpy.cpp b/offload/unittests/OffloadAPI/memory/olMemcpy.cpp index c1762b451b81d..c1fb6df9bad0d 100644 --- a/offload/unittests/OffloadAPI/memory/olMemcpy.cpp +++ b/offload/unittests/OffloadAPI/memory/olMemcpy.cpp @@ -13,6 +13,32 @@ using olMemcpyTest = OffloadQueueTest; OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olMemcpyTest); +struct olMemcpyGlobalTest : OffloadGlobalTest { + void SetUp() override { +RETURN_ON_FATAL_FAILURE(OffloadGlobalTest::SetUp()); +ASSERT_SUCCESS( +olGetSymbol(Program, "read", OL_SYMBOL_KIND_KERNEL, &ReadKernel)); +ASSERT_SUCCESS( +olGetSymbol(Program, "write", OL_SYMBOL_KIND_KERNEL, &WriteKernel)); +ASSERT_SUCCESS(olCreateQueue(Device, &Queue)); +ASSERT_SUCCESS(olGetSymbolInfo( +Global, OL_SYMBOL_INFO_GLOBAL_VARIABLE_ADDRESS, sizeof(Addr), &Addr)); + +LaunchArgs.Dimensions = 1; +LaunchArgs.GroupSize = {64, 1, 1}; +LaunchArgs.NumGroups = {1, 1, 1}; + +LaunchArgs.DynSharedMemory = 0; + } + + ol_kernel
[llvm-branch-commits] [llvm] [CodeGen][NPM] Port ProcessImplicitDefs to NPM (PR #148110)
@@ -0,0 +1,28 @@ +//===- llvm/CodeGen/ProcessImplicitDefs.h ---*- C++ -*-===// +// +// 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 +// +//===--===// + +#ifndef LLVM_CODEGEN_PROCESSIMPLICITDEFS_H +#define LLVM_CODEGEN_PROCESSIMPLICITDEFS_H + +#include "llvm/CodeGen/MachinePassManager.h" + +namespace llvm { + +class ProcessImplicitDefsPass : public PassInfoMixin { +public: + PreservedAnalyses run(MachineFunction &MF, +MachineFunctionAnalysisManager &MFAM); + MachineFunctionProperties getRequiredProperties() const { +return MachineFunctionProperties().set( +MachineFunctionProperties::Property::IsSSA); s-barannikov wrote: ```suggestion return MachineFunctionProperties().setIsSSA(); ``` https://github.com/llvm/llvm-project/pull/148110 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DA] Add check for base pointer invariance (PR #148241)
https://github.com/kasuga-fj updated https://github.com/llvm/llvm-project/pull/148241 >From d914ea5f3c44387570cab65ce9a507ebf429f827 Mon Sep 17 00:00:00 2001 From: Ryotaro Kasuga Date: Fri, 11 Jul 2025 13:10:44 + Subject: [PATCH 1/2] [DA] Add check for base pointer invariance --- llvm/lib/Analysis/DependenceAnalysis.cpp | 16 .../DependenceAnalysis/FlipFlopBaseAddress.ll | 18 +- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp index 428342f51ad2e..07bf560772c8c 100644 --- a/llvm/lib/Analysis/DependenceAnalysis.cpp +++ b/llvm/lib/Analysis/DependenceAnalysis.cpp @@ -3383,6 +3383,10 @@ bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst, SrcSubscripts, DstSubscripts)) return false; + assert(isLoopInvariant(SrcBase, SrcLoop) && + isLoopInvariant(DstBase, DstLoop) && + "Expected SrcBase and DstBase to be loop invariant"); + int Size = SrcSubscripts.size(); LLVM_DEBUG({ dbgs() << "\nSrcSubscripts: "; @@ -3666,6 +3670,18 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst, SCEVUnionPredicate(Assume, *SE)); } + // Even if the base pointers are the same, they may not be loop-invariant. It + // could lead to incorrect results, as we're analyzing loop-carried + // dependencies. + Loop *SrcLoop = LI->getLoopFor(Src->getParent()); + Loop *DstLoop = LI->getLoopFor(Dst->getParent()); + if (!isLoopInvariant(SrcBase, SrcLoop) || + !isLoopInvariant(DstBase, DstLoop)) { +LLVM_DEBUG(dbgs() << "The base pointer is not loop invariant.\n"); +return std::make_unique(Src, Dst, +SCEVUnionPredicate(Assume, *SE)); + } + uint64_t EltSize = SrcLoc.Size.toRaw(); const SCEV *SrcEv = SE->getMinusSCEV(SrcSCEV, SrcBase); const SCEV *DstEv = SE->getMinusSCEV(DstSCEV, DstBase); diff --git a/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll b/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll index 3e3426afab0f7..52cab0f77e73e 100644 --- a/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll +++ b/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll @@ -8,11 +8,11 @@ define float @bug41488_test1(float %f) { ; CHECK-LABEL: 'bug41488_test1' ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float %f, ptr %q, align 4 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store float %f, ptr %q, align 4 --> Dst: store float %f, ptr %q, align 4 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %g = alloca float, align 4 @@ -34,11 +34,11 @@ for.cond.cleanup: define void @bug41488_test2(i32 %n) { ; CHECK-LABEL: 'bug41488_test2' ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float 0.00e+00, ptr %q, align 4 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store float 0.00e+00, ptr %q, align 4 --> Dst: store float 0.00e+00, ptr %q, align 4 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %g = alloca float, align 4 @@ -68,7 +68,7 @@ define void @bug53942_foo(i32 noundef %n, ptr noalias nocapture noundef writeonl ; CHECK-NEXT: Src: %.pre = load double, ptr %B, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store double %.pre, ptr %arrayidx2, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %cmp8 = icmp sgt i32 %n, 1 @@ -99,11 +99,11 @@ for.body: ; preds = %for.body.preheader, define void @bug53942_bar(i32 noundef %n, ptr noalias noundef %A, ptr noalias noundef %B) { ; CHECK-LABEL: 'bug53942_bar' ; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: %0 = load double, ptr %arrayidx, align 8 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store double %0, ptr %arrayidx8, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: br label %for.cond @@ -173,7 +173,7 @@ for.end:
[llvm-branch-commits] [llvm] [DA] Add check for base pointer invariance (PR #148241)
https://github.com/kasuga-fj edited https://github.com/llvm/llvm-project/pull/148241 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DA] Add check for base pointer invariance (PR #148241)
https://github.com/kasuga-fj edited https://github.com/llvm/llvm-project/pull/148241 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [Offload] Add `olGetSymbolInfo[Size]` (PR #147962)
https://github.com/jhuber6 approved this pull request. https://github.com/llvm/llvm-project/pull/147962 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [Offload] Add `olGetSymbolInfo[Size]` (PR #147962)
jhuber6 wrote: > @jhuber6 Given that this interface matches the interface of other handles, > any change to how it fundamentally works should probably involve updating all > other getInfo queries. If we do decide to replace the Size variants, I think > that should be done as a separate task that touches everything. > > For now, I think it makes sense to match other handle points, and leave any > refactors for device info as a separate change that touches everything. Sure, we can get in and then rework all the get info's to just have a separate query for the size. I think that's much cleaner and keeps the number of API functions more clear. I'll accept this for now but we should definitely do that later. https://github.com/llvm/llvm-project/pull/147962 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [DA] Add check for base pointer invariance (PR #148241)
https://github.com/kasuga-fj updated https://github.com/llvm/llvm-project/pull/148241 >From d914ea5f3c44387570cab65ce9a507ebf429f827 Mon Sep 17 00:00:00 2001 From: Ryotaro Kasuga Date: Fri, 11 Jul 2025 13:10:44 + Subject: [PATCH] [DA] Add check for base pointer invariance --- llvm/lib/Analysis/DependenceAnalysis.cpp | 16 .../DependenceAnalysis/FlipFlopBaseAddress.ll | 18 +- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp index 428342f51ad2e..07bf560772c8c 100644 --- a/llvm/lib/Analysis/DependenceAnalysis.cpp +++ b/llvm/lib/Analysis/DependenceAnalysis.cpp @@ -3383,6 +3383,10 @@ bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst, SrcSubscripts, DstSubscripts)) return false; + assert(isLoopInvariant(SrcBase, SrcLoop) && + isLoopInvariant(DstBase, DstLoop) && + "Expected SrcBase and DstBase to be loop invariant"); + int Size = SrcSubscripts.size(); LLVM_DEBUG({ dbgs() << "\nSrcSubscripts: "; @@ -3666,6 +3670,18 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst, SCEVUnionPredicate(Assume, *SE)); } + // Even if the base pointers are the same, they may not be loop-invariant. It + // could lead to incorrect results, as we're analyzing loop-carried + // dependencies. + Loop *SrcLoop = LI->getLoopFor(Src->getParent()); + Loop *DstLoop = LI->getLoopFor(Dst->getParent()); + if (!isLoopInvariant(SrcBase, SrcLoop) || + !isLoopInvariant(DstBase, DstLoop)) { +LLVM_DEBUG(dbgs() << "The base pointer is not loop invariant.\n"); +return std::make_unique(Src, Dst, +SCEVUnionPredicate(Assume, *SE)); + } + uint64_t EltSize = SrcLoc.Size.toRaw(); const SCEV *SrcEv = SE->getMinusSCEV(SrcSCEV, SrcBase); const SCEV *DstEv = SE->getMinusSCEV(DstSCEV, DstBase); diff --git a/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll b/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll index 3e3426afab0f7..52cab0f77e73e 100644 --- a/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll +++ b/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll @@ -8,11 +8,11 @@ define float @bug41488_test1(float %f) { ; CHECK-LABEL: 'bug41488_test1' ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float %f, ptr %q, align 4 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store float %f, ptr %q, align 4 --> Dst: store float %f, ptr %q, align 4 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %g = alloca float, align 4 @@ -34,11 +34,11 @@ for.cond.cleanup: define void @bug41488_test2(i32 %n) { ; CHECK-LABEL: 'bug41488_test2' ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float 0.00e+00, ptr %q, align 4 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store float 0.00e+00, ptr %q, align 4 --> Dst: store float 0.00e+00, ptr %q, align 4 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %g = alloca float, align 4 @@ -68,7 +68,7 @@ define void @bug53942_foo(i32 noundef %n, ptr noalias nocapture noundef writeonl ; CHECK-NEXT: Src: %.pre = load double, ptr %B, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store double %.pre, ptr %arrayidx2, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %cmp8 = icmp sgt i32 %n, 1 @@ -99,11 +99,11 @@ for.body: ; preds = %for.body.preheader, define void @bug53942_bar(i32 noundef %n, ptr noalias noundef %A, ptr noalias noundef %B) { ; CHECK-LABEL: 'bug53942_bar' ; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: %0 = load double, ptr %arrayidx, align 8 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store double %0, ptr %arrayidx8, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: br label %for.cond @@ -173,7 +173,7 @@ for.end:
[llvm-branch-commits] [llvm] [DA] Add check for base pointer invariance (PR #148241)
llvmbot wrote: @llvm/pr-subscribers-llvm-analysis Author: Ryotaro Kasuga (kasuga-fj) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/148241.diff 2 Files Affected: - (modified) llvm/lib/Analysis/DependenceAnalysis.cpp (+16) - (modified) llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll (+9-9) ``diff diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp index 428342f51ad2e..07bf560772c8c 100644 --- a/llvm/lib/Analysis/DependenceAnalysis.cpp +++ b/llvm/lib/Analysis/DependenceAnalysis.cpp @@ -3383,6 +3383,10 @@ bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst, SrcSubscripts, DstSubscripts)) return false; + assert(isLoopInvariant(SrcBase, SrcLoop) && + isLoopInvariant(DstBase, DstLoop) && + "Expected SrcBase and DstBase to be loop invariant"); + int Size = SrcSubscripts.size(); LLVM_DEBUG({ dbgs() << "\nSrcSubscripts: "; @@ -3666,6 +3670,18 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst, SCEVUnionPredicate(Assume, *SE)); } + // Even if the base pointers are the same, they may not be loop-invariant. It + // could lead to incorrect results, as we're analyzing loop-carried + // dependencies. + Loop *SrcLoop = LI->getLoopFor(Src->getParent()); + Loop *DstLoop = LI->getLoopFor(Dst->getParent()); + if (!isLoopInvariant(SrcBase, SrcLoop) || + !isLoopInvariant(DstBase, DstLoop)) { +LLVM_DEBUG(dbgs() << "The base pointer is not loop invariant.\n"); +return std::make_unique(Src, Dst, +SCEVUnionPredicate(Assume, *SE)); + } + uint64_t EltSize = SrcLoc.Size.toRaw(); const SCEV *SrcEv = SE->getMinusSCEV(SrcSCEV, SrcBase); const SCEV *DstEv = SE->getMinusSCEV(DstSCEV, DstBase); diff --git a/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll b/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll index 843c18a6e0d1e..a357018563be1 100644 --- a/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll +++ b/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll @@ -8,11 +8,11 @@ define float @bug41488_test1(float %f) { ; CHECK-LABEL: 'bug41488_test1' ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float %f, ptr %q, align 4 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store float %f, ptr %q, align 4 --> Dst: store float %f, ptr %q, align 4 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %g = alloca float, align 4 @@ -34,11 +34,11 @@ for.cond.cleanup: define void @bug41488_test2(i32 %n) { ; CHECK-LABEL: 'bug41488_test2' ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float 0.00e+00, ptr %q, align 4 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store float 0.00e+00, ptr %q, align 4 --> Dst: store float 0.00e+00, ptr %q, align 4 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %g = alloca float, align 4 @@ -68,7 +68,7 @@ define void @bug53942_foo(i32 noundef %n, ptr noalias nocapture noundef writeonl ; CHECK-NEXT: Src: %.pre = load double, ptr %B, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store double %.pre, ptr %arrayidx2, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %cmp8 = icmp sgt i32 %n, 1 @@ -99,11 +99,11 @@ for.body: ; preds = %for.body.preheader, define void @bug53942_bar(i32 noundef %n, ptr noalias noundef %A, ptr noalias noundef %B) { ; CHECK-LABEL: 'bug53942_bar' ; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: %0 = load double, ptr %arrayidx, align 8 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store double %0, ptr %arrayidx8, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: br label %for.cond @@ -173,7 +173,7 @@ for.end: ; preds = %for.cond.cleanup define void @non_invariant_baseptr_with_identical_obj(ptr %A) {
[llvm-branch-commits] [llvm] [DA] Add check for base pointer invariance (PR #148241)
https://github.com/kasuga-fj created https://github.com/llvm/llvm-project/pull/148241 None >From 3596b1726514dda5942d99d4779852e01367c764 Mon Sep 17 00:00:00 2001 From: Ryotaro Kasuga Date: Fri, 11 Jul 2025 13:10:44 + Subject: [PATCH] [DA] Add check for base pointer invariance --- llvm/lib/Analysis/DependenceAnalysis.cpp | 16 .../DependenceAnalysis/FlipFlopBaseAddress.ll | 18 +- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp index 428342f51ad2e..07bf560772c8c 100644 --- a/llvm/lib/Analysis/DependenceAnalysis.cpp +++ b/llvm/lib/Analysis/DependenceAnalysis.cpp @@ -3383,6 +3383,10 @@ bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst, SrcSubscripts, DstSubscripts)) return false; + assert(isLoopInvariant(SrcBase, SrcLoop) && + isLoopInvariant(DstBase, DstLoop) && + "Expected SrcBase and DstBase to be loop invariant"); + int Size = SrcSubscripts.size(); LLVM_DEBUG({ dbgs() << "\nSrcSubscripts: "; @@ -3666,6 +3670,18 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst, SCEVUnionPredicate(Assume, *SE)); } + // Even if the base pointers are the same, they may not be loop-invariant. It + // could lead to incorrect results, as we're analyzing loop-carried + // dependencies. + Loop *SrcLoop = LI->getLoopFor(Src->getParent()); + Loop *DstLoop = LI->getLoopFor(Dst->getParent()); + if (!isLoopInvariant(SrcBase, SrcLoop) || + !isLoopInvariant(DstBase, DstLoop)) { +LLVM_DEBUG(dbgs() << "The base pointer is not loop invariant.\n"); +return std::make_unique(Src, Dst, +SCEVUnionPredicate(Assume, *SE)); + } + uint64_t EltSize = SrcLoc.Size.toRaw(); const SCEV *SrcEv = SE->getMinusSCEV(SrcSCEV, SrcBase); const SCEV *DstEv = SE->getMinusSCEV(DstSCEV, DstBase); diff --git a/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll b/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll index 843c18a6e0d1e..a357018563be1 100644 --- a/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll +++ b/llvm/test/Analysis/DependenceAnalysis/FlipFlopBaseAddress.ll @@ -8,11 +8,11 @@ define float @bug41488_test1(float %f) { ; CHECK-LABEL: 'bug41488_test1' ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float %f, ptr %q, align 4 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store float %f, ptr %q, align 4 --> Dst: store float %f, ptr %q, align 4 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %g = alloca float, align 4 @@ -34,11 +34,11 @@ for.cond.cleanup: define void @bug41488_test2(i32 %n) { ; CHECK-LABEL: 'bug41488_test2' ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float 0.00e+00, ptr %q, align 4 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store float 0.00e+00, ptr %q, align 4 --> Dst: store float 0.00e+00, ptr %q, align 4 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %g = alloca float, align 4 @@ -68,7 +68,7 @@ define void @bug53942_foo(i32 noundef %n, ptr noalias nocapture noundef writeonl ; CHECK-NEXT: Src: %.pre = load double, ptr %B, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store double %.pre, ptr %arrayidx2, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: %cmp8 = icmp sgt i32 %n, 1 @@ -99,11 +99,11 @@ for.body: ; preds = %for.body.preheader, define void @bug53942_bar(i32 noundef %n, ptr noalias noundef %A, ptr noalias noundef %B) { ; CHECK-LABEL: 'bug53942_bar' ; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: %0 = load double, ptr %arrayidx, align 8 -; CHECK-NEXT:da analyze - input [*]! +; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8 ; CHECK-NEXT:da analyze - confused! ; CHECK-NEXT: Src: store double %0, ptr %arrayidx8, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8 -; CHECK-NEXT:da analyze - output [*]! +; CHECK-NEXT:da analyze - confused! ; entry: br label %for.cond @@ -173,7 +173,7 @@ for.end:
[llvm-branch-commits] [clang] [LifetimeSafety] Add expired loans analysis (PR #148222)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff HEAD~1 HEAD --extensions cpp -- clang/lib/Analysis/LifetimeSafety.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/lib/Analysis/LifetimeSafety.cpp b/clang/lib/Analysis/LifetimeSafety.cpp index 88ec70d00..d95ffcca7 100644 --- a/clang/lib/Analysis/LifetimeSafety.cpp +++ b/clang/lib/Analysis/LifetimeSafety.cpp @@ -783,7 +783,7 @@ public: /// Computes the exit state of a block by applying all its facts sequentially /// to a given entry state. ExpiredLattice transferBlock(const CFGBlock *Block, -ExpiredLattice EntryState) { + ExpiredLattice EntryState) { ExpiredLattice BlockState = EntryState; llvm::ArrayRef Facts = AllFacts.getFacts(Block); @@ -833,8 +833,8 @@ public: for (const CFGBlock *Successor : B->succs()) { auto SuccIt = BlockEntryStates.find(Successor); ExpiredLattice OldSuccEntryState = (SuccIt != BlockEntryStates.end()) -? SuccIt->second -: ExpiredLattice{}; + ? SuccIt->second + : ExpiredLattice{}; ExpiredLattice NewSuccEntryState = OldSuccEntryState.join(ExitState, SetFactory); if (SuccIt == BlockEntryStates.end() || `` https://github.com/llvm/llvm-project/pull/148222 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [LifetimeSafety] Add expired loans analysis (PR #148222)
usx95 wrote: > [!WARNING] > This pull request is not mergeable via GitHub because a downstack PR is > open. Once all requirements are satisfied, merge this PR as a stack href="https://app.graphite.dev/github/pr/llvm/llvm-project/148222?utm_source=stack-comment-downstack-mergeability-warning"; > >on Graphite. > https://graphite.dev/docs/merge-pull-requests";>Learn more * **#148222** https://app.graphite.dev/github/pr/llvm/llvm-project/148222?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/148222?utm_source=stack-comment-view-in-graphite"; target="_blank">(View in Graphite) * **#148065** https://app.graphite.dev/github/pr/llvm/llvm-project/148065?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/>: 1 other dependent PR ([#147315](https://github.com/llvm/llvm-project/pull/147315) https://app.graphite.dev/github/pr/llvm/llvm-project/147315?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/>) * `main` This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn more about https://stacking.dev/?utm_source=stack-comment";>stacking. https://github.com/llvm/llvm-project/pull/148222 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [LifetimeSafety] Add expired loans analysis (PR #148222)
https://github.com/usx95 created https://github.com/llvm/llvm-project/pull/148222 None >From 14a9c8b50df11ce48ce15d0fbe29568b3e23b5a6 Mon Sep 17 00:00:00 2001 From: Utkarsh Saxena Date: Fri, 11 Jul 2025 11:11:47 + Subject: [PATCH] [LifetimeSafety] Add expired loans analysis --- clang/lib/Analysis/LifetimeSafety.cpp | 140 ++ 1 file changed, 140 insertions(+) diff --git a/clang/lib/Analysis/LifetimeSafety.cpp b/clang/lib/Analysis/LifetimeSafety.cpp index e72192aa92c1a..88ec70d000d2c 100644 --- a/clang/lib/Analysis/LifetimeSafety.cpp +++ b/clang/lib/Analysis/LifetimeSafety.cpp @@ -735,6 +735,142 @@ class LifetimeDataflow { } }; +// = // +// Expired Loans Analysis +// = // + +/// The lattice for tracking expired loans. It is a set of loan IDs. +struct ExpiredLattice { + LoanSet Expired; + + ExpiredLattice() = default; + explicit ExpiredLattice(LoanSet S) : Expired(S) {} + + bool operator==(const ExpiredLattice &Other) const { +return Expired == Other.Expired; + } + bool operator!=(const ExpiredLattice &Other) const { +return !(*this == Other); + } + + /// Computes the union of two lattices. + ExpiredLattice join(const ExpiredLattice &Other, + LoanSet::Factory &Factory) const { +LoanSet JoinedSet = Expired; +for (LoanID LID : Other.Expired) + JoinedSet = Factory.add(JoinedSet, LID); +return ExpiredLattice(JoinedSet); + } + + void dump(llvm::raw_ostream &OS) const { +OS << "ExpiredLattice State:\n"; +if (Expired.isEmpty()) + OS << " \n"; +for (const LoanID &LID : Expired) + OS << " Loan " << LID << " is expired\n"; + } +}; + +/// Transfer function for the expired loans analysis. +class ExpiredLoansTransferer { + FactManager &AllFacts; + LoanSet::Factory &SetFactory; + +public: + explicit ExpiredLoansTransferer(FactManager &F, LoanSet::Factory &SF) + : AllFacts(F), SetFactory(SF) {} + + /// Computes the exit state of a block by applying all its facts sequentially + /// to a given entry state. + ExpiredLattice transferBlock(const CFGBlock *Block, +ExpiredLattice EntryState) { +ExpiredLattice BlockState = EntryState; +llvm::ArrayRef Facts = AllFacts.getFacts(Block); + +for (const Fact *F : Facts) { + BlockState = transferFact(BlockState, F); +} +return BlockState; + } + +private: + ExpiredLattice transferFact(ExpiredLattice In, const Fact *F) { +if (const auto *EF = F->getAs()) + return ExpiredLattice(SetFactory.add(In.Expired, EF->getLoanID())); + +if (const auto *IF = F->getAs()) + return ExpiredLattice(SetFactory.remove(In.Expired, IF->getLoanID())); + +return In; + } +}; + +/// Dataflow analysis driver for tracking expired loans. +class ExpiredLoansAnalysis { + const CFG &Cfg; + AnalysisDeclContext &AC; + LoanSet::Factory SetFactory; + ExpiredLoansTransferer Xfer; + + llvm::DenseMap BlockEntryStates; + llvm::DenseMap BlockExitStates; + +public: + ExpiredLoansAnalysis(const CFG &C, FactManager &FS, AnalysisDeclContext &AC) + : Cfg(C), AC(AC), Xfer(FS, SetFactory) {} + + void run() { +llvm::TimeTraceScope TimeProfile("Expired Loans Analysis"); +ForwardDataflowWorklist Worklist(Cfg, AC); +const CFGBlock *Entry = &Cfg.getEntry(); +BlockEntryStates[Entry] = ExpiredLattice(SetFactory.getEmptySet()); +Worklist.enqueueBlock(Entry); +while (const CFGBlock *B = Worklist.dequeue()) { + ExpiredLattice EntryState = getEntryState(B); + ExpiredLattice ExitState = Xfer.transferBlock(B, EntryState); + BlockExitStates[B] = ExitState; + + for (const CFGBlock *Successor : B->succs()) { +auto SuccIt = BlockEntryStates.find(Successor); +ExpiredLattice OldSuccEntryState = (SuccIt != BlockEntryStates.end()) +? SuccIt->second +: ExpiredLattice{}; +ExpiredLattice NewSuccEntryState = +OldSuccEntryState.join(ExitState, SetFactory); +if (SuccIt == BlockEntryStates.end() || +NewSuccEntryState != OldSuccEntryState) { + BlockEntryStates[Successor] = NewSuccEntryState; + Worklist.enqueueBlock(Successor); +} + } +} + } + + void dump() const { +llvm::dbgs() << "==\n"; +llvm::dbgs() << " Expired Loans Results:\n"; +llvm::dbgs() << "==\n"; +const CFGBlock &B = Cfg.getExit(); +getExitState(&B).dump(llvm::dbgs()); + } + + ExpiredLattice getEntryState(const CFGBlock *B) const { +auto It = BlockEntryStates.find(B); +if (It != BlockEntryStates.end()) { + return It->second; +} +return ExpiredLattice(SetFac
[llvm-branch-commits] [flang] [flang][OpenMP] Use OmpDirectiveSpecification in DISPATCH (PR #148008)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/148008 >From 1bcd318939236190a30cfb3259bcb9ca972f1fd3 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 10 Jul 2025 10:18:32 -0500 Subject: [PATCH] [flang][OpenMP] Use OmpDirectiveSpecification in DISPATCH Dispatch is the last construct (after ATOMIC and ALLOCATORS) where the associated block requires a specific form. Using OmpDirectiveSpecification for the begin and the optional end directives will make the structure of all block directives more uniform. --- flang/include/flang/Parser/dump-parse-tree.h | 2 - flang/include/flang/Parser/parse-tree.h | 12 +--- flang/lib/Parser/openmp-parsers.cpp | 36 +++--- flang/lib/Parser/unparse.cpp | 12 +--- flang/lib/Semantics/check-omp-structure.cpp | 25 --- flang/test/Parser/OpenMP/dispatch.f90| 73 flang/test/Semantics/OpenMP/dispatch.f90 | 22 +++--- 7 files changed, 99 insertions(+), 83 deletions(-) diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 73c224e3ad235..32b6ca45609b6 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -710,8 +710,6 @@ class ParseTreeDumper { NODE(parser, OpenMPDepobjConstruct) NODE(parser, OpenMPUtilityConstruct) NODE(parser, OpenMPDispatchConstruct) - NODE(parser, OmpDispatchDirective) - NODE(parser, OmpEndDispatchDirective) NODE(parser, OpenMPFlushConstruct) NODE(parser, OpenMPLoopConstruct) NODE(parser, OpenMPExecutableAllocate) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index fbc39286a95bf..ab2dde7d5dfbe 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4939,19 +4939,11 @@ struct OpenMPDepobjConstruct { //nocontext-clause | //novariants-clause | //nowait-clause -struct OmpDispatchDirective { - TUPLE_CLASS_BOILERPLATE(OmpDispatchDirective); - CharBlock source; - std::tuple t; -}; - -EMPTY_CLASS(OmpEndDispatchDirective); - struct OpenMPDispatchConstruct { TUPLE_CLASS_BOILERPLATE(OpenMPDispatchConstruct); CharBlock source; - std::tuple> + std::tuple> t; }; diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 811ca2c855a6e..d70aaab82cbab 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -1302,6 +1302,32 @@ TYPE_PARSER(sourced( // construct( "ALLOCATORS"_tok >= OmpAllocatorsConstructParser{}))) +struct OmpDispatchConstructParser { + using resultType = OpenMPDispatchConstruct; + + std::optional Parse(ParseState &state) const { +auto dirSpec{Parser{}.Parse(state)}; +if (!dirSpec || dirSpec->DirId() != llvm::omp::Directive::OMPD_dispatch) { + return std::nullopt; +} + +// This should be a function call. That will be checked in semantics. +Block block; +if (auto stmt{attempt(Parser{}).Parse(state)}) { + block.emplace_back(std::move(*stmt)); +} +// Allow empty block. Check for this in semantics. + +auto end{OmpEndDirectiveParser{llvm::omp::Directive::OMPD_dispatch}}; +return OpenMPDispatchConstruct{ +std::move(*dirSpec), std::move(block), *maybe(end).Parse(state)}; + } +}; + +TYPE_PARSER(sourced( // +construct( +"DISPATCH"_tok >= OmpDispatchConstructParser{}))) + // Parser for an arbitrary OpenMP ATOMIC construct. // // Depending on circumstances, an ATOMIC construct applies to one or more @@ -1631,16 +1657,6 @@ TYPE_PARSER(sourced(construct(verbatim("CRITICAL"_tok), TYPE_PARSER(construct( Parser{}, block, Parser{})) -TYPE_PARSER(sourced(construct( -verbatim("DISPATCH"_tok), Parser{}))) - -TYPE_PARSER( -construct(startOmpLine >> "END DISPATCH"_tok)) - -TYPE_PARSER(sourced(construct( -Parser{} / endOmpLine, block, -maybe(Parser{} / endOmpLine - // 2.11.3 Executable Allocate directive TYPE_PARSER( sourced(construct(verbatim("ALLOCATE"_tok), diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 4f692f3e9084f..b66d756bdbf2c 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2758,6 +2758,9 @@ class UnparseVisitor { Put("\n"); EndOpenMP(); } + void Unparse(const OpenMPDispatchConstruct &x) { // +UnparseBlockConstruct(x); + } void Unparse(const OpenMPRequiresConstruct &y) { BeginOpenMP(); Word("!$OMP REQUIRES "); @@ -2777,15 +2780,6 @@ class UnparseVisitor { Walk(x.v); return false; } - void Unparse(const OmpDispatchDirective &x) { -Word("!$OMP DISPATCH"); -Walk(x.t); -Put("\n"); - } - void Unparse(const OmpEndDispatchDirective &) { -Word("!$OMP END DISPATCH"); -Put("\n"); - } void Unparse(const OmpErrorDirective &x) {
[llvm-branch-commits] [llvm] 43535be - Revert "[RISCV] AddEdge between mask producer and user of V0 (#146855)"
Author: Pengcheng Wang Date: 2025-07-11T18:59:23+08:00 New Revision: 43535be8ab3f6ffadd161358823d90c713c9d7be URL: https://github.com/llvm/llvm-project/commit/43535be8ab3f6ffadd161358823d90c713c9d7be DIFF: https://github.com/llvm/llvm-project/commit/43535be8ab3f6ffadd161358823d90c713c9d7be.diff LOG: Revert "[RISCV] AddEdge between mask producer and user of V0 (#146855)" This reverts commit aee21c368b41cd5f7765a31b9dbe77f2bffadd4e. Added: Modified: llvm/lib/Target/RISCV/RISCVVectorMaskDAGMutation.cpp llvm/test/CodeGen/RISCV/rvv/combine-reduce-add-to-vcpop.ll llvm/test/CodeGen/RISCV/rvv/extractelt-i1.ll llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-i1.ll llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-deinterleave.ll llvm/test/CodeGen/RISCV/rvv/vscale-vw-web-simplification.ll llvm/test/CodeGen/RISCV/rvv/vselect-fp.ll Removed: diff --git a/llvm/lib/Target/RISCV/RISCVVectorMaskDAGMutation.cpp b/llvm/lib/Target/RISCV/RISCVVectorMaskDAGMutation.cpp index 5464612d86bee..be54a8c95a978 100644 --- a/llvm/lib/Target/RISCV/RISCVVectorMaskDAGMutation.cpp +++ b/llvm/lib/Target/RISCV/RISCVVectorMaskDAGMutation.cpp @@ -10,10 +10,6 @@ // instructions and masked instructions, so that we can reduce the live range // overlaps of mask registers. // -// If there are multiple masks producers followed by multiple masked -// instructions, then at each masked instructions add dependency edges between -// every producer and masked instruction. -// // The reason why we need to do this: // 1. When tracking register pressure, we don't track physical registers. // 2. We have a RegisterClass for mask register (which is `VMV0`), but we don't @@ -72,25 +68,11 @@ class RISCVVectorMaskDAGMutation : public ScheduleDAGMutation { void apply(ScheduleDAGInstrs *DAG) override { SUnit *NearestUseV0SU = nullptr; -SmallVector DefMask; for (SUnit &SU : DAG->SUnits) { const MachineInstr *MI = SU.getInstr(); - if (isSoleUseCopyToV0(SU)) -DefMask.push_back(&SU); - - if (MI->findRegisterUseOperand(RISCV::V0, TRI)) { + if (MI->findRegisterUseOperand(RISCV::V0, TRI)) NearestUseV0SU = &SU; -// Copy may not be a real use, so skip it here. -if (DefMask.size() > 1 && !MI->isCopy()) - for (SUnit *Def : DefMask) -if (DAG->canAddEdge(Def, &SU)) - DAG->addEdge(Def, SDep(&SU, SDep::Artificial)); - -if (!DefMask.empty()) - DefMask.erase(DefMask.begin()); - } - if (NearestUseV0SU && NearestUseV0SU != &SU && isSoleUseCopyToV0(SU) && // For LMUL=8 cases, there will be more possibilities to spill. // FIXME: We should use RegPressureTracker to do fine-grained diff --git a/llvm/test/CodeGen/RISCV/rvv/combine-reduce-add-to-vcpop.ll b/llvm/test/CodeGen/RISCV/rvv/combine-reduce-add-to-vcpop.ll index 2d4fce68f9545..0d8aff306252e 100644 --- a/llvm/test/CodeGen/RISCV/rvv/combine-reduce-add-to-vcpop.ll +++ b/llvm/test/CodeGen/RISCV/rvv/combine-reduce-add-to-vcpop.ll @@ -313,12 +313,12 @@ define i32 @test_nxv128i1( %x) { ; CHECK-NEXT:vslidedown.vx v0, v6, a0 ; CHECK-NEXT:vsetvli a2, zero, e8, m1, ta, ma ; CHECK-NEXT:vslidedown.vx v6, v7, a1 -; CHECK-NEXT:vsetvli a1, zero, e32, m8, ta, ma -; CHECK-NEXT:vmerge.vim v8, v8, 1, v0 ; CHECK-NEXT:vsetvli a1, zero, e8, mf2, ta, ma -; CHECK-NEXT:vslidedown.vx v0, v7, a0 ; CHECK-NEXT:vslidedown.vx v5, v6, a0 +; CHECK-NEXT:vslidedown.vx v4, v7, a0 ; CHECK-NEXT:vsetvli a0, zero, e32, m8, ta, mu +; CHECK-NEXT:vmerge.vim v8, v8, 1, v0 +; CHECK-NEXT:vmv1r.v v0, v4 ; CHECK-NEXT:vadd.vi v8, v8, 1, v0.t ; CHECK-NEXT:vmv1r.v v0, v5 ; CHECK-NEXT:vadd.vi v16, v16, 1, v0.t @@ -425,15 +425,13 @@ define i32 @test_nxv256i1( %x) { ; CHECK-NEXT:vmerge.vim v16, v8, 1, v0 ; CHECK-NEXT:vsetvli a2, zero, e8, mf2, ta, ma ; CHECK-NEXT:vslidedown.vx v0, v5, a1 -; CHECK-NEXT:vsetvli a2, zero, e32, m8, ta, ma -; CHECK-NEXT:vmerge.vim v8, v8, 1, v0 -; CHECK-NEXT:vsetvli a2, zero, e8, mf2, ta, ma -; CHECK-NEXT:vslidedown.vx v0, v6, a1 +; CHECK-NEXT:vslidedown.vx v5, v7, a1 +; CHECK-NEXT:vslidedown.vx v4, v6, a1 ; CHECK-NEXT:vsetvli a2, zero, e32, m8, ta, mu +; CHECK-NEXT:vmerge.vim v8, v8, 1, v0 +; CHECK-NEXT:vmv1r.v v0, v4 ; CHECK-NEXT:vadd.vi v8, v8, 1, v0.t -; CHECK-NEXT:vsetvli a2, zero, e8, mf2, ta, ma -; CHECK-NEXT:vslidedown.vx v0, v7, a1 -; CHECK-NEXT:vsetvli a2, zero, e32, m8, ta, mu +; CHECK-NEXT:vmv1r.v v0, v5 ; CHECK-NEXT:vadd.vi v16, v16, 1, v0.t ; CHECK-NEXT:vadd.vv v8, v16, v8 ; CHECK-NEXT:addi a2, sp, 16 diff --git a/llvm/test/CodeGen/RISCV/rvv/extractelt-i1.ll b/llvm/test/CodeGen/RISCV/rvv/extractelt-i1.ll index 15417da962bd3..796f8dde58f47 100644 --- a/llvm/test/CodeGen/RISCV/rvv/extracte
[llvm-branch-commits] [clang] [LifetimeSafety] Add script for performance benchmarking (PR #147315)
https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/147315 >From 7d9009c2f22bf3f0980f7fd811be3185192490cf Mon Sep 17 00:00:00 2001 From: Utkarsh Saxena Date: Mon, 7 Jul 2025 15:13:00 + Subject: [PATCH] [LifetimeSafety] Add script performance benchmarking --- .../Analysis/LifetimeSafety/CMakeLists.txt| 49 +++ .../test/Analysis/LifetimeSafety/benchmark.py | 307 ++ .../Analysis/LifetimeSafety/requirements.txt | 2 + clang/test/CMakeLists.txt | 2 + 4 files changed, 360 insertions(+) create mode 100644 clang/test/Analysis/LifetimeSafety/CMakeLists.txt create mode 100644 clang/test/Analysis/LifetimeSafety/benchmark.py create mode 100644 clang/test/Analysis/LifetimeSafety/requirements.txt diff --git a/clang/test/Analysis/LifetimeSafety/CMakeLists.txt b/clang/test/Analysis/LifetimeSafety/CMakeLists.txt new file mode 100644 index 0..ce37a29655668 --- /dev/null +++ b/clang/test/Analysis/LifetimeSafety/CMakeLists.txt @@ -0,0 +1,49 @@ +# = +# Lifetime Analysis Benchmarking Target +# = +# This target allows running performance benchmarks for the clang lifetime analysis +# using a Python script (with managed dependencies). + +find_package(Python3 COMPONENTS Interpreter REQUIRED) + +# Define paths for the virtual environment and requirements file. +set(LIFETIME_BENCHMARK_SCRIPT + "${CMAKE_CURRENT_SOURCE_DIR}/benchmark.py") +set(LIFETIME_BENCHMARK_VENV_DIR "${CMAKE_CURRENT_BINARY_DIR}/benchmark-venv") +set(LIFETIME_BENCHMARK_REQUIREMENTS + "${CMAKE_CURRENT_SOURCE_DIR}/requirements.txt") +set(LIFETIME_BENCHMARK_OUTPUT_DIR + "${CMAKE_CURRENT_BINARY_DIR}/benchmark_results") + + +if(EXISTS ${LIFETIME_BENCHMARK_SCRIPT} AND EXISTS ${LIFETIME_BENCHMARK_REQUIREMENTS}) + + # Set up the virtual environment and install packages + add_custom_command( +OUTPUT ${LIFETIME_BENCHMARK_VENV_DIR}/pyvenv.cfg +COMMAND ${Python3_EXECUTABLE} -m venv ${LIFETIME_BENCHMARK_VENV_DIR} +COMMAND ${LIFETIME_BENCHMARK_VENV_DIR}/bin/python -m pip install -r ${LIFETIME_BENCHMARK_REQUIREMENTS} +DEPENDS ${LIFETIME_BENCHMARK_REQUIREMENTS} +COMMENT "Creating Python virtual environment and installing dependencies for benchmark..." + ) + add_custom_target(benchmark_venv_setup +DEPENDS ${LIFETIME_BENCHMARK_VENV_DIR}/pyvenv.cfg + ) + + # Main benchmark target + add_custom_target(benchmark_lifetime_safety_analysis +COMMAND ${LIFETIME_BENCHMARK_VENV_DIR}/bin/python ${LIFETIME_BENCHMARK_SCRIPT} +--clang-binary ${LLVM_BINARY_DIR}/bin/clang +--output-dir ${LIFETIME_BENCHMARK_OUTPUT_DIR} + +DEPENDS clang benchmark_venv_setup + +# Display the output directly in the console. +USES_TERMINAL + +COMMENT "Running Lifetime Analysis performance benchmarks..." + ) + + set_target_properties(benchmark_lifetime_safety_analysis +PROPERTIES FOLDER "Clang/Benchmarks") +endif() diff --git a/clang/test/Analysis/LifetimeSafety/benchmark.py b/clang/test/Analysis/LifetimeSafety/benchmark.py new file mode 100644 index 0..9d5f36c51b9ee --- /dev/null +++ b/clang/test/Analysis/LifetimeSafety/benchmark.py @@ -0,0 +1,307 @@ +import sys +import argparse +import subprocess +import tempfile +import json +import os +from datetime import datetime +import numpy as np +from scipy.optimize import curve_fit +from scipy.stats import t + + +def generate_cpp_cycle_test(n: int) -> str: +""" +Generates a C++ code snippet with a specified number of pointers in a cycle. +Creates a while loop that rotates N pointers. +This pattern tests the convergence speed of the dataflow analysis when +reaching its fixed point. + +Example: +struct MyObj { int id; ~MyObj() {} }; + +void long_cycle_4(bool condition) { +MyObj v1{1}; +MyObj v2{1}; +MyObj v3{1}; +MyObj v4{1}; + +MyObj* p1 = &v1; +MyObj* p2 = &v2; +MyObj* p3 = &v3; +MyObj* p4 = &v4; + +while (condition) { +MyObj* temp = p1; +p1 = p2; +p2 = p3; +p3 = p4; +p4 = temp; +} +} +""" +if n <= 0: +return "// Number of variables must be positive." + +cpp_code = "struct MyObj { int id; ~MyObj() {} };\n\n" +cpp_code += f"void long_cycle_{n}(bool condition) {{\n" +for i in range(1, n + 1): +cpp_code += f" MyObj v{i}{{1}};\n" +cpp_code += "\n" +for i in range(1, n + 1): +cpp_code += f" MyObj* p{i} = &v{i};\n" + +cpp_code += "\n while (condition) {\n" +if n > 0: +cpp_code += f"MyObj* temp = p1;\n" +for i in range(1, n): +cpp_code += f"p{i} = p{i+1};\n" +cpp_code += f"
[llvm-branch-commits] [llvm] [AMDGPU][SDAG] Test ISD::PTRADD handling in various special cases (PR #145329)
https://github.com/arsenm approved this pull request. https://github.com/llvm/llvm-project/pull/145329 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [CodeGen][NPM] Port ProcessImplicitDefs to NPM (PR #148110)
https://github.com/arsenm approved this pull request. https://github.com/llvm/llvm-project/pull/148110 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AMDGPU][NPM] Add isRequired to passes missing it (PR #148115)
https://github.com/cdevadas approved this pull request. https://github.com/llvm/llvm-project/pull/148115 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [CodeGen][NPM] Stitch up loop passes in codegen pipeline (PR #148114)
https://github.com/cdevadas approved this pull request. https://github.com/llvm/llvm-project/pull/148114 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [CodeGen][NPM] Clear MachineFunctions without using PA (PR #148113)
https://github.com/cdevadas approved this pull request. https://github.com/llvm/llvm-project/pull/148113 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [AMDGPU][NPM] Fill in addPreSched2 passes (PR #148112)
https://github.com/cdevadas approved this pull request. https://github.com/llvm/llvm-project/pull/148112 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [CodeGen][NPM] Account inserted passes for -start/stop options (PR #148111)
https://github.com/cdevadas approved this pull request. https://github.com/llvm/llvm-project/pull/148111 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [CodeGen][NPM] Account inserted passes for -start/stop options (PR #148111)
@@ -579,8 +579,10 @@ template class CodeGenPassBuilder { void insertPass(InsertedPassT &&Pass) const { AfterCallbacks.emplace_back( [&](StringRef Name, MachineFunctionPassManager &MFPM) mutable { - if (Name == TargetPassT::name()) -MFPM.addPass(std::forward(Pass)); + if (Name == TargetPassT::name()) { +if (runBeforeAdding(InsertedPassT::name())) + MFPM.addPass(std::forward(Pass)); + } cdevadas wrote: ```suggestion if (Name == TargetPassT::name() && runBeforeAdding(InsertedPassT::name())) MFPM.addPass(std::forward(Pass)); ``` https://github.com/llvm/llvm-project/pull/148111 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits