[llvm-branch-commits] [compiler-rt] [llvm] [NFC] (PR #80762)
bwendling wrote: Please add a title and description. https://github.com/llvm/llvm-project/pull/80762 ___ 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] release/18.x: [Clang] Handle structs with inner structs and no fields (#89126) (PR #89456)
bwendling wrote: @tstellar The output is definitely different. It needs 90ba33099cbb17e7c159e9ebc5a512037db99d6d, which looks to be only in `main`. I can generate a patch, since porting that change will probably be onerous. How do I do that for the 18.X branch? https://github.com/llvm/llvm-project/pull/89456 ___ 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] [Clang] Handle structs with inner structs and no fields (#89126) (PR #90133)
https://github.com/bwendling created https://github.com/llvm/llvm-project/pull/90133 A struct that declares an inner struct, but no fields, won't have a field count. So getting the offset of the inner struct fails. This happens in both C and C++: struct foo { struct bar { int Quantizermatrix[]; }; }; Here 'struct foo' has no fields. Closes: https://github.com/llvm/llvm-project/issues/88931 >From 504a17cc62a5c333f6228de0a70f04420da3efcc Mon Sep 17 00:00:00 2001 From: Bill Wendling <5993918+bwendl...@users.noreply.github.com> Date: Fri, 19 Apr 2024 12:48:33 -0700 Subject: [PATCH] [Clang] Handle structs with inner structs and no fields (#89126) A struct that declares an inner struct, but no fields, won't have a field count. So getting the offset of the inner struct fails. This happens in both C and C++: struct foo { struct bar { int Quantizermatrix[]; }; }; Here 'struct foo' has no fields. Closes: https://github.com/llvm/llvm-project/issues/88931 --- clang/lib/CodeGen/CGBuiltin.cpp | 25 +++- clang/test/CodeGen/attr-counted-by-pr88931.c | 40 +++ .../test/CodeGen/attr-counted-by-pr88931.cpp | 21 ++ 3 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 clang/test/CodeGen/attr-counted-by-pr88931.c create mode 100644 clang/test/CodeGen/attr-counted-by-pr88931.cpp diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index a4f26a6f0eb19b..44ddd2428b10f5 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -823,29 +823,32 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField( ASTContext &Ctx, const RecordDecl *RD, StringRef Name, uint64_t &Offset) { const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = getLangOpts().getStrictFlexArraysLevel(); - unsigned FieldNo = 0; - bool IsUnion = RD->isUnion(); + uint32_t FieldNo = 0; - for (const Decl *D : RD->decls()) { -if (const auto *Field = dyn_cast(D); -Field && (Name.empty() || Field->getNameAsString() == Name) && + if (RD->isImplicit()) +return nullptr; + + for (const FieldDecl *FD : RD->fields()) { +if ((Name.empty() || FD->getNameAsString() == Name) && Decl::isFlexibleArrayMemberLike( -Ctx, Field, Field->getType(), StrictFlexArraysLevel, +Ctx, FD, FD->getType(), StrictFlexArraysLevel, /*IgnoreTemplateOrMacroSubstitution=*/true)) { const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); Offset += Layout.getFieldOffset(FieldNo); - return Field; + return FD; } -if (const auto *Record = dyn_cast(D)) - if (const FieldDecl *Field = - FindFlexibleArrayMemberField(Ctx, Record, Name, Offset)) { +QualType Ty = FD->getType(); +if (Ty->isRecordType()) { + if (const FieldDecl *Field = FindFlexibleArrayMemberField( + Ctx, Ty->getAsRecordDecl(), Name, Offset)) { const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); Offset += Layout.getFieldOffset(FieldNo); return Field; } +} -if (!IsUnion && isa(D)) +if (!RD->isUnion()) ++FieldNo; } diff --git a/clang/test/CodeGen/attr-counted-by-pr88931.c b/clang/test/CodeGen/attr-counted-by-pr88931.c new file mode 100644 index 00..520ebd09973284 --- /dev/null +++ b/clang/test/CodeGen/attr-counted-by-pr88931.c @@ -0,0 +1,40 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -Wno-missing-declarations -emit-llvm -o - %s | FileCheck %s + +struct foo { + int x,y,z; + struct bar { +int count; +int array[] __attribute__((counted_by(count))); + }; +}; + +void init(void * __attribute__((pass_dynamic_object_size(0; + +// CHECK-LABEL: define dso_local void @test1( +// CHECK-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT:[[ARRAY:%.*]] = getelementptr inbounds [[STRUCT_BAR:%.*]], ptr [[P]], i64 0, i32 1 +// CHECK-NEXT:tail call void @init(ptr noundef nonnull [[ARRAY]], i64 noundef -1) #[[ATTR2:[0-9]+]] +// CHECK-NEXT:ret void +// +void test1(struct bar *p) { + init(p->array); +} + +struct mux { + int count; + int array[] __attribute__((counted_by(count))); +}; + +struct bux { struct mux x; }; + +// CHECK-LABEL: define dso_local void @test2( +// CHECK-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT:tail call void @init(ptr noundef [[P]], i64 noundef -1) #[[ATTR2]] +// CHECK-NEXT:ret void +// +void test2(struct bux *p) { + init(p); +} diff --git a/clang/test/CodeGen/attr-counted-by-pr88931.cpp b/clang/test/CodeGen/attr-counted-by-pr88931.cpp new file mode 100644 index 00..2a8cc1d07e50d9 --- /dev/null +++ b/clang/test/CodeGen/attr-counted-b
[llvm-branch-commits] [clang] [Clang] Handle structs with inner structs and no fields (#89126) (PR #90133)
https://github.com/bwendling milestoned https://github.com/llvm/llvm-project/pull/90133 ___ 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] [Clang] Handle structs with inner structs and no fields (#89126) (PR #90133)
bwendling wrote: Okay...I think this works now? https://github.com/llvm/llvm-project/pull/90133 ___ 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] [Clang] Handle structs with inner structs and no fields (#89126) (PR #90133)
bwendling wrote: Fixed an issue with the counted_by attribute on a flexible array member in an inner struct. https://github.com/llvm/llvm-project/pull/90133 ___ 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] e222953 - [X86] Add segment and address-size override prefixes
Author: Bill Wendling Date: 2021-01-19T23:54:31-08:00 New Revision: e22295385c7fb1104620a497da8eab935768fd78 URL: https://github.com/llvm/llvm-project/commit/e22295385c7fb1104620a497da8eab935768fd78 DIFF: https://github.com/llvm/llvm-project/commit/e22295385c7fb1104620a497da8eab935768fd78.diff LOG: [X86] Add segment and address-size override prefixes X86 allows for the "addr32" and "addr16" address size override prefixes. Also, these and the segment override prefixes should be recognized as valid prefixes. Differential Revision: https://reviews.llvm.org/D94726 Added: llvm/test/MC/X86/addr16-32.s llvm/test/MC/X86/segment-prefix.s Modified: llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp llvm/lib/Target/X86/X86InstrSystem.td Removed: diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 406327e46f32..e4ffe3f71100 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -3260,11 +3260,13 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, // repz repnz ; GAS errors for the use of two similar prefixes // lock addq %rax, %rbx ; Destination operand must be of memory type // xacquire ; xacquire must be accompanied by 'lock' - bool isPrefix = StringSwitch(Name) - .Cases("rex64", "data32", "data16", true) - .Cases("xacquire", "xrelease", true) - .Cases("acquire", "release", isParsingIntelSyntax()) - .Default(false); + bool IsPrefix = + StringSwitch(Name) + .Cases("cs", "ds", "es", "fs", "gs", "ss", true) + .Cases("rex64", "data32", "data16", "addr32", "addr16", true) + .Cases("xacquire", "xrelease", true) + .Cases("acquire", "release", isParsingIntelSyntax()) + .Default(false); auto isLockRepeatNtPrefix = [](StringRef N) { return StringSwitch(N) @@ -,7 +3335,7 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, Name = Next; PatchedName = Name; ForcedDataPrefix = X86::Mode32Bit; - isPrefix = false; + IsPrefix = false; } } @@ -3350,7 +3352,7 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we // just want to parse the "lock" as the first instruction and the "incl" as // the next one. - if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) { + if (getLexer().isNot(AsmToken::EndOfStatement) && !IsPrefix) { // Parse '*' modifier. if (getLexer().is(AsmToken::Star)) Operands.push_back(X86Operand::CreateToken("*", consumeToken())); @@ -3387,7 +3389,7 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, // Consume the EndOfStatement or the prefix separator Slash if (getLexer().is(AsmToken::EndOfStatement) || - (isPrefix && getLexer().is(AsmToken::Slash))) + (IsPrefix && getLexer().is(AsmToken::Slash))) Parser.Lex(); else if (CurlyAsEndOfStatement) // Add an actual EndOfStatement before the curly brace diff --git a/llvm/lib/Target/X86/X86InstrSystem.td b/llvm/lib/Target/X86/X86InstrSystem.td index f57ca7ffec7f..eb8740896e5d 100644 --- a/llvm/lib/Target/X86/X86InstrSystem.td +++ b/llvm/lib/Target/X86/X86InstrSystem.td @@ -171,6 +171,17 @@ def FS_PREFIX : I<0x64, PrefixByte, (outs), (ins), "fs", []>; def GS_PREFIX : I<0x65, PrefixByte, (outs), (ins), "gs", []>; } // SchedRW +//===--===// +// Address-size override prefixes. +// + +let SchedRW = [WriteNop] in { +def ADDR16_PREFIX : I<0x67, PrefixByte, (outs), (ins), "addr16", []>, + Requires<[In32BitMode]>; +def ADDR32_PREFIX : I<0x67, PrefixByte, (outs), (ins), "addr32", []>, + Requires<[In64BitMode]>; +} // SchedRW + //===--===// // Moves to and from segment registers. // diff --git a/llvm/test/MC/X86/addr16-32.s b/llvm/test/MC/X86/addr16-32.s new file mode 100644 index ..8812ee8bd609 --- /dev/null +++ b/llvm/test/MC/X86/addr16-32.s @@ -0,0 +1,23 @@ +# RUN: llvm-mc %s -triple x86_64-linux-gnu -filetype=obj -o - | llvm-objdump -d - | FileCheck %s + +.text +.global foo +foo: + insl + gs outsl + .code64 + addr32 insl + addr32 gs outsl + .code32 + addr16 insl + addr16 gs outsl + .code64 + retq + +# CHECK: : +# CHECK-NEXT: 6dinsl %dx, %es:(%rdi) +# CHECK-NEXT: 65 6f outsl %gs:(%rsi), %dx +# CHECK-NEXT: 67 6d insl %dx, %es:(%edi) +# CHECK-N
[llvm-branch-commits] [clang] d37c5ce - [randstruct] Add randomize structure layout support
Author: Connor Kuehl Date: 2022-04-08T12:44:15-07:00 New Revision: d37c5cea2f9829bbbd8e9e6a78539e84e5cc725b URL: https://github.com/llvm/llvm-project/commit/d37c5cea2f9829bbbd8e9e6a78539e84e5cc725b DIFF: https://github.com/llvm/llvm-project/commit/d37c5cea2f9829bbbd8e9e6a78539e84e5cc725b.diff LOG: [randstruct] Add randomize structure layout support The Randstruct feature is a compile-time hardening technique that randomizes the field layout for designated structures of a code base. Admittedly, this is mostly useful for closed-source releases of code, since the randomization seed would need to be available for public and open source applications. Why implement it? This patch set enhances Clang’s feature parity with that of GCC which already has the Randstruct feature. It's used by the Linux kernel in certain structures to help thwart attacks that depend on structure layouts in memory. This patch set is a from-scratch reimplementation of the Randstruct feature that was originally ported to GCC. The patches for the GCC implementation can be found here: https://www.openwall.com/lists/kernel-hardening/2017/04/06/14 Link: https://lists.llvm.org/pipermail/cfe-dev/2019-March/061607.html Co-authored-by: Cole Nixon Co-authored-by: Connor Kuehl Co-authored-by: James Foster Co-authored-by: Jeff Takahashi Co-authored-by: Jordan Cantrell Co-authored-by: Nikk Forbus Co-authored-by: Tim Pugh Co-authored-by: Bill Wendling Signed-off-by: Bill Wendling Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D121556 Added: clang/include/clang/AST/Randstruct.h clang/lib/AST/Randstruct.cpp clang/unittests/AST/RandstructTest.cpp Modified: clang/docs/ReleaseNotes.rst clang/include/clang/AST/Decl.h clang/include/clang/AST/DeclBase.h clang/include/clang/Basic/Attr.td clang/include/clang/Basic/AttrDocs.td clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/LangOptions.h clang/include/clang/Driver/Options.td clang/lib/AST/CMakeLists.txt clang/lib/AST/Decl.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/lib/Sema/SemaCast.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/test/Misc/pragma-attribute-supported-attributes-list.test clang/unittests/AST/CMakeLists.txt Removed: diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index df6a7d7539ee6..2729213ffe70b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -54,6 +54,20 @@ Major New Features There is an analogous ``zero_call_used_regs`` attribute to allow for finer control of this feature. +- Clang now supports randomizing structure layout in C. This feature is a + compile-time hardening technique, making it more diff icult for an attacker to + retrieve data from structures. Specify randomization with the + ``randomize_layout`` attribute. The corresponding ``no_randomize_layout`` + attribute can be used to turn the feature off. + + A seed value is required to enable randomization, and is deterministic based + on a seed value. Use the ``-frandomize-layout-seed=`` or + ``-frandomize-layout-seed-file=`` flags. + + .. note:: + + Randomizing structure layout is a C-only feature. + Bug Fixes -- - ``CXXNewExpr::getArraySize()`` previously returned a ``llvm::Optional`` diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 1246287ee2e62..21a8545920387 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -4051,6 +4051,12 @@ class RecordDecl : public TagDecl { RecordDeclBits.ParamDestroyedInCallee = V; } + bool isRandomized() const { return RecordDeclBits.IsRandomized; } + + void setIsRandomized(bool V) { RecordDeclBits.IsRandomized = V; } + + void reorderFields(const SmallVectorImpl &Fields); + /// Determines whether this declaration represents the /// injected class name. /// diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index a89f776248c1f..a4a44e0b30e64 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -313,6 +313,7 @@ class alignas(8) Decl { friend class ASTReader; friend class CXXClassMemberWrapper; friend class LinkageComputer; + friend class RecordDecl; template friend class Redeclarable; /// Access - Used by C++ decls for the access specifier. @@ -1540,10 +1541,13 @@ class DeclContext { /// Represents the way this type is passed to a function. uint64_t ArgPassingRestrictions : 2; + +/// Indicates whether this struct has had its field layout randomized. +uint64_t IsRandomized : 1; }; /// Number of non-inherited bits in RecordDeclBitfields. - e
[llvm-branch-commits] [llvm] d497129 - [AArch64] Use proper instruction mnemonics for FPRs
Author: Bill Wendling Date: 2022-05-20T12:02:26-07:00 New Revision: d497129f9bfaeff9fd2a57d75186ef0966758ca4 URL: https://github.com/llvm/llvm-project/commit/d497129f9bfaeff9fd2a57d75186ef0966758ca4 DIFF: https://github.com/llvm/llvm-project/commit/d497129f9bfaeff9fd2a57d75186ef0966758ca4.diff LOG: [AArch64] Use proper instruction mnemonics for FPRs The FPR128 regs need MOVIv2d_ns and SVE regs need DUP_ZI_D. Differential Revision: https://reviews.llvm.org/D126083 Added: Modified: llvm/lib/Target/AArch64/AArch64FrameLowering.cpp llvm/test/CodeGen/AArch64/zero-call-used-regs.ll Removed: diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 399a4e19ce2f8..52e782c7eff52 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -793,7 +793,12 @@ void AArch64FrameLowering::emitZeroCallUsedRegs(BitVector RegsToZero, // Zero out FP/vector registers. for (MCRegister Reg : FPRsToZero.set_bits()) -BuildMI(MBB, MBBI, DL, TII.get(AArch64::MOVID), Reg).addImm(0); +if (HasSVE) + BuildMI(MBB, MBBI, DL, TII.get(AArch64::DUP_ZI_D), Reg) +.addImm(0) +.addImm(0); +else + BuildMI(MBB, MBBI, DL, TII.get(AArch64::MOVIv2d_ns), Reg).addImm(0); if (HasSVE) { for (MCRegister PReg : diff --git a/llvm/test/CodeGen/AArch64/zero-call-used-regs.ll b/llvm/test/CodeGen/AArch64/zero-call-used-regs.ll index b9425a6b8018d..c39089908713b 100644 --- a/llvm/test/CodeGen/AArch64/zero-call-used-regs.ll +++ b/llvm/test/CodeGen/AArch64/zero-call-used-regs.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s --check-prefixes=CHECK,DEFAULT -; RUN: llc < %s -mtriple=aarch64-unknown-unknown -mattr=+sve | FileCheck %s --check-prefixes=CHECK,SVE +; RUN: llc < %s -verify-machineinstrs -mtriple=aarch64-unknown-unknown | FileCheck %s --check-prefixes=CHECK,DEFAULT +; RUN: llc < %s -verify-machineinstrs -mtriple=aarch64-unknown-unknown -mattr=+sve | FileCheck %s --check-prefixes=CHECK,SVE @result = dso_local global i32 0, align 4 @@ -146,14 +146,14 @@ define dso_local i32 @all_arg(i32 noundef %a, i32 noundef %b, i32 noundef %c) lo ; DEFAULT-NEXT:mov x7, #0 ; DEFAULT-NEXT:mov x8, #0 ; DEFAULT-NEXT:mov x18, #0 -; DEFAULT-NEXT:movi q0, # -; DEFAULT-NEXT:movi q1, # -; DEFAULT-NEXT:movi q2, # -; DEFAULT-NEXT:movi q3, # -; DEFAULT-NEXT:movi q4, # -; DEFAULT-NEXT:movi q5, # -; DEFAULT-NEXT:movi q6, # -; DEFAULT-NEXT:movi q7, # +; DEFAULT-NEXT:movi v0.2d, # +; DEFAULT-NEXT:movi v1.2d, # +; DEFAULT-NEXT:movi v2.2d, # +; DEFAULT-NEXT:movi v3.2d, # +; DEFAULT-NEXT:movi v4.2d, # +; DEFAULT-NEXT:movi v5.2d, # +; DEFAULT-NEXT:movi v6.2d, # +; DEFAULT-NEXT:movi v7.2d, # ; DEFAULT-NEXT:ret ; ; SVE-LABEL: all_arg: @@ -169,14 +169,14 @@ define dso_local i32 @all_arg(i32 noundef %a, i32 noundef %b, i32 noundef %c) lo ; SVE-NEXT:mov x7, #0 ; SVE-NEXT:mov x8, #0 ; SVE-NEXT:mov x18, #0 -; SVE-NEXT:movi z0, # -; SVE-NEXT:movi z1, # -; SVE-NEXT:movi z2, # -; SVE-NEXT:movi z3, # -; SVE-NEXT:movi z4, # -; SVE-NEXT:movi z5, # -; SVE-NEXT:movi z6, # -; SVE-NEXT:movi z7, # +; SVE-NEXT:mov z0.d, #0 // =0x0 +; SVE-NEXT:mov z1.d, #0 // =0x0 +; SVE-NEXT:mov z2.d, #0 // =0x0 +; SVE-NEXT:mov z3.d, #0 // =0x0 +; SVE-NEXT:mov z4.d, #0 // =0x0 +; SVE-NEXT:mov z5.d, #0 // =0x0 +; SVE-NEXT:mov z6.d, #0 // =0x0 +; SVE-NEXT:mov z7.d, #0 // =0x0 ; SVE-NEXT:pfalse p0.b ; SVE-NEXT:pfalse p1.b ; SVE-NEXT:pfalse p2.b @@ -212,38 +212,38 @@ define dso_local i32 @all(i32 noundef %a, i32 noundef %b, i32 noundef %c) local_ ; DEFAULT-NEXT:mov x16, #0 ; DEFAULT-NEXT:mov x17, #0 ; DEFAULT-NEXT:mov x18, #0 -; DEFAULT-NEXT:movi q0, # -; DEFAULT-NEXT:movi q1, # -; DEFAULT-NEXT:movi q2, # -; DEFAULT-NEXT:movi q3, # -; DEFAULT-NEXT:movi q4, # -; DEFAULT-NEXT:movi q5, # -; DEFAULT-NEXT:movi q6, # -; DEFAULT-NEXT:movi q7, # -; DEFAULT-NEXT:movi q8, # -; DEFAULT-NEXT:movi q9, # -; DEFAULT-NEXT:movi q10, # -; DEFAULT-NEXT
[llvm-branch-commits] [llvm] 14d4cdd - [X86] Don't zero out %eax if both %al and %ah are used
Author: Bill Wendling Date: 2022-12-13T15:06:53-08:00 New Revision: 14d4cddc5506fb0fd3c4ac556b4edd970aa151eb URL: https://github.com/llvm/llvm-project/commit/14d4cddc5506fb0fd3c4ac556b4edd970aa151eb DIFF: https://github.com/llvm/llvm-project/commit/14d4cddc5506fb0fd3c4ac556b4edd970aa151eb.diff LOG: [X86] Don't zero out %eax if both %al and %ah are used The iterator over super and sub registers doesn't include both 8-bit registers in its list. So if both registers are used and only one of them is live on return, then we need to make sure that the other 8-bit register is also marked as live and not zeroed out. Reviewed By: nickdesaulniers Differential Revision: https://reviews.llvm.org/D139679 Added: llvm/test/CodeGen/X86/zero-call-used-regs-i386.ll Modified: llvm/lib/CodeGen/PrologEpilogInserter.cpp Removed: diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index dbfd8b936da5..4e32c1049f0a 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -1282,7 +1282,13 @@ void PEI::insertZeroCallUsedRegs(MachineFunction &MF) { if (!MO.isReg()) continue; -for (MCPhysReg SReg : TRI.sub_and_superregs_inclusive(MO.getReg())) +MCRegister Reg = MO.getReg(); + +// This picks up sibling registers (e.q. %al -> %ah). +for (MCRegUnitIterator Unit(Reg, &TRI); Unit.isValid(); ++Unit) + RegsToZero.reset(*Unit); + +for (MCPhysReg SReg : TRI.sub_and_superregs_inclusive(Reg)) RegsToZero.reset(SReg); } } diff --git a/llvm/test/CodeGen/X86/zero-call-used-regs-i386.ll b/llvm/test/CodeGen/X86/zero-call-used-regs-i386.ll new file mode 100644 index ..33e501ca8503 --- /dev/null +++ b/llvm/test/CodeGen/X86/zero-call-used-regs-i386.ll @@ -0,0 +1,112 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -opaque-pointers | FileCheck %s --check-prefix=I386 +; +; Make sure we don't zero out %eax when both %ah and %al are used. +; +; PR1766: https://github.com/ClangBuiltLinux/linux/issues/1766 + +%struct.maple_subtree_state = type { ptr } + +@mas_data_end_type = dso_local local_unnamed_addr global i32 0, align 4 +@ma_meta_end_mn_0_0_0_0_0_0 = dso_local local_unnamed_addr global i8 0, align 1 +@mt_pivots_0 = dso_local local_unnamed_addr global i8 0, align 1 +@mas_data_end___trans_tmp_2 = dso_local local_unnamed_addr global ptr null, align 4 +@mt_slots_0 = dso_local local_unnamed_addr global i8 0, align 1 + +define dso_local zeroext i1 @test1(ptr nocapture noundef readonly %0) local_unnamed_addr "zero-call-used-regs"="used-gpr" nounwind { +; I386-LABEL: test1: +; I386: # %bb.0: +; I386-NEXT:pushl %ebx +; I386-NEXT:subl $24, %esp +; I386-NEXT:movl {{[0-9]+}}(%esp), %eax +; I386-NEXT:movl (%eax), %eax +; I386-NEXT:movzbl (%eax), %ebx +; I386-NEXT:calll bar +; I386-NEXT:testb %al, %al +; I386-NEXT:# implicit-def: $al +; I386-NEXT:# kill: killed $al +; I386-NEXT:je .LBB0_6 +; I386-NEXT: # %bb.1: +; I386-NEXT:cmpl $0, mas_data_end_type +; I386-NEXT:je .LBB0_3 +; I386-NEXT: # %bb.2: +; I386-NEXT:movzbl ma_meta_end_mn_0_0_0_0_0_0, %eax +; I386-NEXT:movb %al, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill +; I386-NEXT:jmp .LBB0_6 +; I386-NEXT: .LBB0_3: +; I386-NEXT:movb mt_pivots_0, %ah +; I386-NEXT:movb %ah, %al +; I386-NEXT:decb %al +; I386-NEXT:movl mas_data_end___trans_tmp_2, %ecx +; I386-NEXT:movsbl %al, %edx +; I386-NEXT:cmpl $0, (%ecx,%edx,4) +; I386-NEXT:je .LBB0_5 +; I386-NEXT: # %bb.4: +; I386-NEXT:movb %al, %ah +; I386-NEXT: .LBB0_5: +; I386-NEXT:movb %ah, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill +; I386-NEXT: .LBB0_6: +; I386-NEXT:movb mt_slots_0, %bh +; I386-NEXT:leal {{[0-9]+}}(%esp), %eax +; I386-NEXT:movl %eax, (%esp) +; I386-NEXT:calll baz +; I386-NEXT:subl $4, %esp +; I386-NEXT:cmpb %bh, %bl +; I386-NEXT:jae .LBB0_8 +; I386-NEXT: # %bb.7: +; I386-NEXT:movsbl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 1-byte Folded Reload +; I386-NEXT:movl %eax, (%esp) +; I386-NEXT:calll gaz +; I386-NEXT: .LBB0_8: +; I386-NEXT:movb $1, %al +; I386-NEXT:addl $24, %esp +; I386-NEXT:popl %ebx +; I386-NEXT:xorl %ecx, %ecx +; I386-NEXT:xorl %edx, %edx +; I386-NEXT:retl + %2 = alloca %struct.maple_subtree_state, align 4 + %3 = load ptr, ptr %0, align 4 + %4 = load i8, ptr %3, align 1 + %5 = tail call zeroext i1 @bar() + br i1 %5, label %6, label %20 + +6:; preds = %1 + %7 = load i32, ptr @mas_data_end_type, align 4 + %8 = icmp eq i32 %7, 0 + br i1 %8, label %11, label %9 + +9:; preds = %6 + %10 = load i8, ptr @ma
[llvm-branch-commits] [clang] [Clang] Fix 'counted_by' for nested struct pointers (#110497) (PR #111445)
https://github.com/bwendling updated https://github.com/llvm/llvm-project/pull/111445 >From f414a24fd7ad173793f920157bfa95985a09a946 Mon Sep 17 00:00:00 2001 From: Jan Hendrik Farr Date: Thu, 3 Oct 2024 07:16:21 +0200 Subject: [PATCH 1/2] [Clang] Fix 'counted_by' for nested struct pointers (#110497) Fix counted_by attribute for cases where the flexible array member is accessed through struct pointer inside another struct: ``` struct variable { int a; int b; int length; short array[] __attribute__((counted_by(length))); }; struct bucket { int a; struct variable *growable; int b; }; ``` __builtin_dynamic_object_size(p->growable->array, 0); This commit makes sure that if the StructBase is both a MemberExpr and a pointer, it is treated as a pointer. Otherwise clang will generate to code to access the address of p->growable intead of loading the value of p->growable->length. Fixes #110385 --- clang/lib/CodeGen/CGExpr.cpp | 16 ++-- clang/test/CodeGen/attr-counted-by-pr110385.c | 70 clang/test/CodeGen/attr-counted-by.c | 80 +-- 3 files changed, 117 insertions(+), 49 deletions(-) create mode 100644 clang/test/CodeGen/attr-counted-by-pr110385.c diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 5f58a64d8386c3..8d6f535bba896e 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1052,6 +1052,8 @@ class StructAccessBase return Visit(E->getBase()); } const Expr *VisitCastExpr(const CastExpr *E) { +if (E->getCastKind() == CK_LValueToRValue) + return E; return Visit(E->getSubExpr()); } const Expr *VisitParenExpr(const ParenExpr *E) { @@ -1119,19 +1121,15 @@ llvm::Value *CodeGenFunction::EmitCountedByFieldExpr( return nullptr; llvm::Value *Res = nullptr; - if (const auto *DRE = dyn_cast(StructBase)) { -Res = EmitDeclRefLValue(DRE).getPointer(*this); -Res = Builder.CreateAlignedLoad(ConvertType(DRE->getType()), Res, -getPointerAlign(), "dre.load"); - } else if (const MemberExpr *ME = dyn_cast(StructBase)) { -LValue LV = EmitMemberExpr(ME); -Address Addr = LV.getAddress(); -Res = Addr.emitRawPointer(*this); - } else if (StructBase->getType()->isPointerType()) { + if (StructBase->getType()->isPointerType()) { LValueBaseInfo BaseInfo; TBAAAccessInfo TBAAInfo; Address Addr = EmitPointerWithAlignment(StructBase, &BaseInfo, &TBAAInfo); Res = Addr.emitRawPointer(*this); + } else if (StructBase->isLValue()) { +LValue LV = EmitLValue(StructBase); +Address Addr = LV.getAddress(); +Res = Addr.emitRawPointer(*this); } else { return nullptr; } diff --git a/clang/test/CodeGen/attr-counted-by-pr110385.c b/clang/test/CodeGen/attr-counted-by-pr110385.c new file mode 100644 index 00..6891d5abe7d5c2 --- /dev/null +++ b/clang/test/CodeGen/attr-counted-by-pr110385.c @@ -0,0 +1,70 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -Wno-missing-declarations -emit-llvm -o - %s | FileCheck %s + +// See #110385 +// Based on reproducer from Kees Cook: +// https://lore.kernel.org/all/202409170436.C3C6E7F7A@keescook/ + +struct variable { +int a; +int b; +int length; +short array[] __attribute__((counted_by(length))); +}; + +struct bucket { +int a; +struct variable *growable; +int b; +}; + +struct bucket2 { +int a; +struct variable growable; +}; + +void init(void * __attribute__((pass_dynamic_object_size(0; + +// CHECK-LABEL: define dso_local void @test1( +// CHECK-SAME: ptr nocapture noundef readonly [[FOO:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT:[[GROWABLE:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 8 +// CHECK-NEXT:[[TMP0:%.*]] = load ptr, ptr [[GROWABLE]], align 8, !tbaa [[TBAA2:![0-9]+]] +// CHECK-NEXT:[[ARRAY:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 12 +// CHECK-NEXT:[[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8 +// CHECK-NEXT:[[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 +// CHECK-NEXT:[[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// CHECK-NEXT:[[TMP2:%.*]] = shl nsw i64 [[TMP1]], 1 +// CHECK-NEXT:[[TMP3:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], -1 +// CHECK-NEXT:[[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 +// CHECK-NEXT:tail call void @init(ptr noundef nonnull [[ARRAY]], i64 noundef [[TMP4]]) #[[ATTR2:[0-9]+]] +// CHECK-NEXT:ret void +// +void test1(struct bucket *foo) { +init(foo->growable->array); +} + +// CHECK-LABEL: define dso_local void @test2( +// CHECK-SAME: ptr noundef [[FOO:%.*]]) local_unnamed_addr #[[ATTR
[llvm-branch-commits] [clang] [Clang] Fix 'counted_by' for nested struct pointers (#110497) (PR #111445)
https://github.com/bwendling created https://github.com/llvm/llvm-project/pull/111445 /cherry-pick >From f414a24fd7ad173793f920157bfa95985a09a946 Mon Sep 17 00:00:00 2001 From: Jan Hendrik Farr Date: Thu, 3 Oct 2024 07:16:21 +0200 Subject: [PATCH] [Clang] Fix 'counted_by' for nested struct pointers (#110497) Fix counted_by attribute for cases where the flexible array member is accessed through struct pointer inside another struct: ``` struct variable { int a; int b; int length; short array[] __attribute__((counted_by(length))); }; struct bucket { int a; struct variable *growable; int b; }; ``` __builtin_dynamic_object_size(p->growable->array, 0); This commit makes sure that if the StructBase is both a MemberExpr and a pointer, it is treated as a pointer. Otherwise clang will generate to code to access the address of p->growable intead of loading the value of p->growable->length. Fixes #110385 --- clang/lib/CodeGen/CGExpr.cpp | 16 ++-- clang/test/CodeGen/attr-counted-by-pr110385.c | 70 clang/test/CodeGen/attr-counted-by.c | 80 +-- 3 files changed, 117 insertions(+), 49 deletions(-) create mode 100644 clang/test/CodeGen/attr-counted-by-pr110385.c diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 5f58a64d8386c3..8d6f535bba896e 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1052,6 +1052,8 @@ class StructAccessBase return Visit(E->getBase()); } const Expr *VisitCastExpr(const CastExpr *E) { +if (E->getCastKind() == CK_LValueToRValue) + return E; return Visit(E->getSubExpr()); } const Expr *VisitParenExpr(const ParenExpr *E) { @@ -1119,19 +1121,15 @@ llvm::Value *CodeGenFunction::EmitCountedByFieldExpr( return nullptr; llvm::Value *Res = nullptr; - if (const auto *DRE = dyn_cast(StructBase)) { -Res = EmitDeclRefLValue(DRE).getPointer(*this); -Res = Builder.CreateAlignedLoad(ConvertType(DRE->getType()), Res, -getPointerAlign(), "dre.load"); - } else if (const MemberExpr *ME = dyn_cast(StructBase)) { -LValue LV = EmitMemberExpr(ME); -Address Addr = LV.getAddress(); -Res = Addr.emitRawPointer(*this); - } else if (StructBase->getType()->isPointerType()) { + if (StructBase->getType()->isPointerType()) { LValueBaseInfo BaseInfo; TBAAAccessInfo TBAAInfo; Address Addr = EmitPointerWithAlignment(StructBase, &BaseInfo, &TBAAInfo); Res = Addr.emitRawPointer(*this); + } else if (StructBase->isLValue()) { +LValue LV = EmitLValue(StructBase); +Address Addr = LV.getAddress(); +Res = Addr.emitRawPointer(*this); } else { return nullptr; } diff --git a/clang/test/CodeGen/attr-counted-by-pr110385.c b/clang/test/CodeGen/attr-counted-by-pr110385.c new file mode 100644 index 00..6891d5abe7d5c2 --- /dev/null +++ b/clang/test/CodeGen/attr-counted-by-pr110385.c @@ -0,0 +1,70 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -Wno-missing-declarations -emit-llvm -o - %s | FileCheck %s + +// See #110385 +// Based on reproducer from Kees Cook: +// https://lore.kernel.org/all/202409170436.C3C6E7F7A@keescook/ + +struct variable { +int a; +int b; +int length; +short array[] __attribute__((counted_by(length))); +}; + +struct bucket { +int a; +struct variable *growable; +int b; +}; + +struct bucket2 { +int a; +struct variable growable; +}; + +void init(void * __attribute__((pass_dynamic_object_size(0; + +// CHECK-LABEL: define dso_local void @test1( +// CHECK-SAME: ptr nocapture noundef readonly [[FOO:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT:[[GROWABLE:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 8 +// CHECK-NEXT:[[TMP0:%.*]] = load ptr, ptr [[GROWABLE]], align 8, !tbaa [[TBAA2:![0-9]+]] +// CHECK-NEXT:[[ARRAY:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 12 +// CHECK-NEXT:[[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8 +// CHECK-NEXT:[[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 +// CHECK-NEXT:[[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// CHECK-NEXT:[[TMP2:%.*]] = shl nsw i64 [[TMP1]], 1 +// CHECK-NEXT:[[TMP3:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], -1 +// CHECK-NEXT:[[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 +// CHECK-NEXT:tail call void @init(ptr noundef nonnull [[ARRAY]], i64 noundef [[TMP4]]) #[[ATTR2:[0-9]+]] +// CHECK-NEXT:ret void +// +void test1(struct bucket *foo) { +init(foo->growable->array); +} + +// CHECK-LABEL: define dso_local void @test2( +// CHECK-SAME: ptr noundef [[FOO:%.*]]) local_unnamed_add
[llvm-branch-commits] [clang] [Clang] Fix 'counted_by' for nested struct pointers (#110497) (PR #111445)
https://github.com/bwendling milestoned https://github.com/llvm/llvm-project/pull/111445 ___ 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] [Clang] Fix 'counted_by' for nested struct pointers (#110497) (PR #111445)
https://github.com/bwendling edited https://github.com/llvm/llvm-project/pull/111445 ___ 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] [Clang] Disable use of the counted_by attribute for whole struct pointers (#112636) (PR #112786)
https://github.com/bwendling created https://github.com/llvm/llvm-project/pull/112786 The whole struct is specificed in the __bdos. The calculation of the whole size of the structure can be done in two ways: 1) sizeof(struct S) + count * sizeof(typeof(fam)) 2) offsetof(struct S, fam) + count * sizeof(typeof(fam)) The first will add any remaining whitespace that might exist after allocation while the second method is more precise, but not quite expected from programmers. See [1] for a discussion of the topic. GCC isn't (currently) able to calculate __bdos on a pointer to the whole structure. Therefore, because of the above issue, we'll choose to match what GCC does for consistency's sake. [1] https://lore.kernel.org/lkml/ZvV6X5FPBBW7CO1f@archlinux/ >From 5ef6cde2a99774d3a2da8773cec45323098f7db1 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Thu, 17 Oct 2024 21:52:40 + Subject: [PATCH] [Clang] Disable use of the counted_by attribute for whole struct pointers (#112636) The whole struct is specificed in the __bdos. The calculation of the whole size of the structure can be done in two ways: 1) sizeof(struct S) + count * sizeof(typeof(fam)) 2) offsetof(struct S, fam) + count * sizeof(typeof(fam)) The first will add any remaining whitespace that might exist after allocation while the second method is more precise, but not quite expected from programmers. See [1] for a discussion of the topic. GCC isn't (currently) able to calculate __bdos on a pointer to the whole structure. Therefore, because of the above issue, we'll choose to match what GCC does for consistency's sake. [1] https://lore.kernel.org/lkml/ZvV6X5FPBBW7CO1f@archlinux/ Co-authored-by: Eli Friedman --- clang/lib/CodeGen/CGBuiltin.cpp | 45 +++-- clang/test/CodeGen/attr-counted-by.c | 253 +-- 2 files changed, 107 insertions(+), 191 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 5639239359ab82..86d47054615e67 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1001,6 +1001,24 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, // Can't find the field referenced by the "counted_by" attribute. return nullptr; + if (isa(Base)) +// The whole struct is specificed in the __bdos. The calculation of the +// whole size of the structure can be done in two ways: +// +// 1) sizeof(struct S) + count * sizeof(typeof(fam)) +// 2) offsetof(struct S, fam) + count * sizeof(typeof(fam)) +// +// The first will add additional padding after the end of the array, +// allocation while the second method is more precise, but not quite +// expected from programmers. See +// https://lore.kernel.org/lkml/ZvV6X5FPBBW7CO1f@archlinux/ for a +// discussion of the topic. +// +// GCC isn't (currently) able to calculate __bdos on a pointer to the whole +// structure. Therefore, because of the above issue, we'll choose to match +// what GCC does for consistency's sake. +return nullptr; + // Build a load of the counted_by field. bool IsSigned = CountedByFD->getType()->isSignedIntegerType(); Value *CountedByInst = EmitCountedByFieldExpr(Base, FAMDecl, CountedByFD); @@ -1031,32 +1049,9 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, CharUnits Size = Ctx.getTypeSizeInChars(ArrayTy->getElementType()); llvm::Constant *ElemSize = llvm::ConstantInt::get(ResType, Size.getQuantity(), IsSigned); - Value *FAMSize = + Value *Res = Builder.CreateMul(CountedByInst, ElemSize, "", !IsSigned, IsSigned); - FAMSize = Builder.CreateIntCast(FAMSize, ResType, IsSigned); - Value *Res = FAMSize; - - if (isa(Base)) { -// The whole struct is specificed in the __bdos. -const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(OuterRD); - -// Get the offset of the FAM. -llvm::Constant *FAMOffset = ConstantInt::get(ResType, Offset, IsSigned); -Value *OffsetAndFAMSize = -Builder.CreateAdd(FAMOffset, Res, "", !IsSigned, IsSigned); - -// Get the full size of the struct. -llvm::Constant *SizeofStruct = -ConstantInt::get(ResType, Layout.getSize().getQuantity(), IsSigned); - -// max(sizeof(struct s), -// offsetof(struct s, array) + p->count * sizeof(*p->array)) -Res = IsSigned - ? Builder.CreateBinaryIntrinsic(llvm::Intrinsic::smax, - OffsetAndFAMSize, SizeofStruct) - : Builder.CreateBinaryIntrinsic(llvm::Intrinsic::umax, - OffsetAndFAMSize, SizeofStruct); - } + Res = Builder.CreateIntCast(Res, ResType, IsSigned); // A negative \p IdxInst or \p CountedByInst means that the index lands // outside of the flexible array member. If that's the case, we want to diff --git a/clang/test/CodeGen/attr-counted-by.c b/cl
[llvm-branch-commits] [clang] [Clang] Disable use of the counted_by attribute for whole struct pointers (#112636) (PR #112786)
https://github.com/bwendling milestoned https://github.com/llvm/llvm-project/pull/112786 ___ 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] [Clang] Disable use of the counted_by attribute for whole struct pointers (#112636) (PR #112786)
https://github.com/bwendling edited https://github.com/llvm/llvm-project/pull/112786 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits