Skip to content

Commit d6c2e8c

Browse files
authored
merge main into amd-staging (#611)
2 parents 7d6a25a + fc0b487 commit d6c2e8c

File tree

259 files changed

+8779
-4569
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

259 files changed

+8779
-4569
lines changed

.ci/premerge_advisor_explain.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def get_comment(
3939
) -> dict[str, str]:
4040
repo = github.Github(github_token).get_repo("llvm/llvm-project")
4141
pr = repo.get_issue(pr_number).as_pull_request()
42+
body = COMMENT_TAG.format(platform=platform.system()) + "\n" + body
4243
comment = {"body": body}
4344
comment_id = get_comment_id(platform.system(), pr)
4445
if comment_id:
@@ -128,7 +129,7 @@ def main(
128129
),
129130
)
130131
]
131-
with open("comment", "w") as comment_file_handle:
132+
with open("comments", "w") as comment_file_handle:
132133
json.dump(comments, comment_file_handle)
133134
else:
134135
print(advisor_response.reason)

.github/workflows/libc-fullbuild-tests.yml

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,42 @@ jobs:
4848
cpp_compiler: clang++-22
4949
target: x86_64-unknown-uefi-llvm
5050
include_scudo: OFF
51+
- os: ubuntu-24.04
52+
build_type: MinSizeRel
53+
c_compiler: clang-22
54+
cpp_compiler: clang++-22
55+
target: armv6m-none-eabi
56+
include_scudo: OFF
57+
- os: ubuntu-24.04
58+
build_type: MinSizeRel
59+
c_compiler: clang-22
60+
cpp_compiler: clang++-22
61+
target: armv7m-none-eabi
62+
include_scudo: OFF
63+
- os: ubuntu-24.04
64+
build_type: MinSizeRel
65+
c_compiler: clang-22
66+
cpp_compiler: clang++-22
67+
target: armv7em-none-eabi
68+
include_scudo: OFF
69+
- os: ubuntu-24.04
70+
build_type: MinSizeRel
71+
c_compiler: clang-22
72+
cpp_compiler: clang++-22
73+
target: armv8m.main-none-eabi
74+
include_scudo: OFF
75+
- os: ubuntu-24.04
76+
build_type: MinSizeRel
77+
c_compiler: clang-22
78+
cpp_compiler: clang++-22
79+
target: armv8.1m.main-none-eabi
80+
include_scudo: OFF
81+
- os: ubuntu-24.04
82+
build_type: MinSizeRel
83+
c_compiler: clang-22
84+
cpp_compiler: clang++-22
85+
target: riscv32-unknown-elf
86+
include_scudo: OFF
5187
# TODO: add back gcc build when it is fixed
5288
# - c_compiler: gcc
5389
# cpp_compiler: g++
@@ -93,28 +129,39 @@ jobs:
93129
run: |
94130
export RUNTIMES="libc"
95131
132+
export CMAKE_FLAGS="
133+
-G Ninja
134+
-S ${{ github.workspace }}/runtimes
135+
-B ${{ steps.strings.outputs.build-output-dir }}
136+
-DCMAKE_ASM_COMPILER=${{ matrix.c_compiler }}
137+
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
138+
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
139+
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
140+
-DCMAKE_C_COMPILER_LAUNCHER=sccache
141+
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
142+
-DCMAKE_INSTALL_PREFIX=${{ steps.strings.outputs.build-install-dir }}"
143+
96144
if [[ ${{ matrix.include_scudo}} == "ON" ]]; then
97145
export RUNTIMES="$RUNTIMES;compiler-rt"
98-
export CMAKE_FLAGS="
146+
export CMAKE_FLAGS="$CMAKE_FLAGS
99147
-DLLVM_LIBC_INCLUDE_SCUDO=ON
100148
-DCOMPILER_RT_BUILD_SCUDO_STANDALONE_WITH_LLVM_LIBC=ON
101149
-DCOMPILER_RT_BUILD_GWP_ASAN=OFF
102150
-DCOMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED=OFF"
103151
fi
104152
105-
cmake -B ${{ steps.strings.outputs.build-output-dir }} \
106-
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} \
107-
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }} \
108-
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
109-
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
110-
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache \
111-
-DCMAKE_INSTALL_PREFIX=${{ steps.strings.outputs.build-install-dir }} \
112-
-DLLVM_RUNTIME_TARGETS=${{ matrix.target }} \
113-
-DLLVM_ENABLE_RUNTIMES="$RUNTIMES" \
114-
-DLLVM_LIBC_FULL_BUILD=ON \
115-
-G Ninja \
116-
-S ${{ github.workspace }}/runtimes \
117-
$CMAKE_FLAGS
153+
case "${{ matrix.target }}" in
154+
*-none-eabi|riscv32-unknown-elf)
155+
cmake $CMAKE_FLAGS \
156+
-C ${{ github.workspace }}/libc/cmake/caches/${{ matrix.target }}.cmake
157+
;;
158+
*)
159+
cmake -DLLVM_RUNTIME_TARGETS=${{ matrix.target }} \
160+
-DLLVM_ENABLE_RUNTIMES="$RUNTIMES" \
161+
-DLLVM_LIBC_FULL_BUILD=ON \
162+
$CMAKE_FLAGS
163+
;;
164+
esac
118165
119166
- name: Build
120167
run: >
@@ -124,8 +171,12 @@ jobs:
124171
--target install
125172
126173
- name: Test
127-
# Skip UEFI tests until we have testing set up.
128-
if: ${{ ! endsWith(matrix.target, '-uefi-llvm') }}
174+
# Skip UEFI and baremetal tests until we have testing set up.
175+
if: ${{
176+
!endsWith(matrix.target, '-uefi-llvm') &&
177+
!endsWith(matrix.target, '-none-eabi') &&
178+
matrix.target != 'riscv32-unknown-elf'
179+
}}
129180
run: >
130181
cmake
131182
--build ${{ steps.strings.outputs.build-output-dir }}

.github/workflows/premerge.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ jobs:
119119
path: artifacts/
120120
retention-days: 5
121121
include-hidden-files: 'true'
122+
- name: Upload Comment
123+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
124+
if: ${{ always() && !startsWith(matrix.runs-on, 'depot-ubuntu-24.04-arm') }}
125+
continue-on-error: true
126+
with:
127+
name: workflow-args
128+
path: |
129+
comments
122130
123131
premerge-checks-windows:
124132
name: Build and Test Windows

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ autoconf/autom4te.cache
5454
/cmake-build*
5555
# Coding assistants' stuff
5656
/CLAUDE.md
57-
/.claude/
57+
.claude/
5858
/GEMINI.md
59-
/.gemini/
59+
.gemini/
6060

6161
#==============================================================================#
6262
# Directories to ignore (do not add trailing '/'s, they skip symlinks).

clang/include/clang/CIR/Dialect/IR/CIRAttrs.td

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,4 +1026,29 @@ def CIR_UnwindAttr : CIR_UnitAttr<"Unwind", "unwind"> {
10261026
let storageType = [{ CatchUnwind }];
10271027
}
10281028

1029+
//===----------------------------------------------------------------------===//
1030+
// CIR_BlockAddrInfoAttr
1031+
//===----------------------------------------------------------------------===//
1032+
1033+
def CIR_BlockAddrInfoAttr : CIR_Attr<"BlockAddrInfo", "block_addr_info"> {
1034+
let summary = "Block Addres attribute";
1035+
let description = [{
1036+
This attribute is used to represent the address of a basic block
1037+
within a function. It combines the symbol reference to a function
1038+
with the name of a label inside that function.
1039+
}];
1040+
let parameters = (ins "mlir::FlatSymbolRefAttr":$func,
1041+
"mlir::StringAttr":$label);
1042+
1043+
let assemblyFormat = "`<` $func `,` $label `>`";
1044+
let builders = [
1045+
AttrBuilder<(ins "llvm::StringRef":$func_name,
1046+
"llvm::StringRef":$label_name
1047+
), [{
1048+
return $_get($_ctxt, mlir::FlatSymbolRefAttr::get($_ctxt, func_name),
1049+
mlir::StringAttr::get($_ctxt, label_name));
1050+
}]>
1051+
];
1052+
}
1053+
10291054
#endif // CLANG_CIR_DIALECT_IR_CIRATTRS_TD

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3386,6 +3386,10 @@ def CIR_BaseClassAddrOp : CIR_Op<"base_class_addr"> {
33863386
cannot be known by the operation, and that information affects how the
33873387
operation is lowered.
33883388

3389+
The validity of the relationship of derived and base cannot yet be verified.
3390+
If the target class is not a valid base class for the object, the behavior
3391+
is undefined.
3392+
33893393
Example:
33903394
```c++
33913395
struct Base { };
@@ -3399,8 +3403,6 @@ def CIR_BaseClassAddrOp : CIR_Op<"base_class_addr"> {
33993403
```
34003404
}];
34013405

3402-
// The validity of the relationship of derived and base cannot yet be
3403-
// verified, currently not worth adding a verifier.
34043406
let arguments = (ins
34053407
Arg<CIR_PointerType, "derived class pointer", [MemRead]>:$derived_addr,
34063408
IndexAttr:$offset, UnitAttr:$assume_not_null);
@@ -3414,6 +3416,56 @@ def CIR_BaseClassAddrOp : CIR_Op<"base_class_addr"> {
34143416
}];
34153417
}
34163418

3419+
//===----------------------------------------------------------------------===//
3420+
// DerivedClassAddrOp
3421+
//===----------------------------------------------------------------------===//
3422+
3423+
def CIR_DerivedClassAddrOp : CIR_Op<"derived_class_addr"> {
3424+
let summary = "Get the derived class address for a class/struct";
3425+
let description = [{
3426+
The `cir.derived_class_addr` operaration gets the address of a particular
3427+
derived class given a non-virtual base class pointer. The offset in bytes
3428+
of the base class must be passed in, similar to `cir.base_class_addr`, but
3429+
going into the other direction. This means lowering to a negative offset.
3430+
3431+
The operation contains a flag for whether or not the operand may be nullptr.
3432+
That depends on the context and cannot be known by the operation, and that
3433+
information affects how the operation is lowered.
3434+
3435+
The validity of the relationship of derived and base cannot yet be verified.
3436+
If the target class is not a valid derived class for the object, the
3437+
behavior is undefined.
3438+
3439+
Example:
3440+
```c++
3441+
class A {};
3442+
class B : public A {};
3443+
3444+
B *getAsB(A *a) {
3445+
return static_cast<B*>(a);
3446+
}
3447+
```
3448+
3449+
leads to
3450+
```mlir
3451+
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!rec_A>>, !cir.ptr<!rec_A>
3452+
%3 = cir.base_class_addr %2 : !cir.ptr<!rec_B> [0] -> !cir.ptr<!rec_A>
3453+
```
3454+
}];
3455+
3456+
let arguments = (ins
3457+
Arg<CIR_PointerType, "base class pointer", [MemRead]>:$base_addr,
3458+
IndexAttr:$offset, UnitAttr:$assume_not_null);
3459+
3460+
let results = (outs Res<CIR_PointerType, "">:$derived_addr);
3461+
3462+
let assemblyFormat = [{
3463+
$base_addr `:` qualified(type($base_addr))
3464+
(`nonnull` $assume_not_null^)?
3465+
` ` `[` $offset `]` `->` qualified(type($derived_addr)) attr-dict
3466+
}];
3467+
}
3468+
34173469
//===----------------------------------------------------------------------===//
34183470
// ComplexCreateOp
34193471
//===----------------------------------------------------------------------===//
@@ -4845,4 +4897,38 @@ def CIR_AtomicClearOp : CIR_Op<"atomic.clear"> {
48454897
}];
48464898
}
48474899

4900+
//===----------------------------------------------------------------------===//
4901+
// BlockAddressOp
4902+
//===----------------------------------------------------------------------===//
4903+
4904+
def CIR_BlockAddressOp : CIR_Op<"block_address", [Pure]> {
4905+
let summary = "Get the address of a cir.label within a function";
4906+
let description = [{
4907+
The `cir.blockaddress` operation takes a function name and a label and
4908+
produces a pointer value that represents the address of that cir.label
4909+
within the specified function.
4910+
4911+
This operation models GCC's "labels as values" extension (`&&label`), which
4912+
allows taking the address of a local label and using it as a computed
4913+
jump target (e.g., with `goto *addr;`).
4914+
4915+
Example:
4916+
```mlir
4917+
%1 = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr", init]
4918+
{alignment = 8 : i64}
4919+
%addr = cir.block_address <@c, "label1"> : !cir.ptr<!cir.void>
4920+
cir.store align(8) %addr, %1 : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
4921+
cir.br ^bb1
4922+
^bb1:
4923+
cir.label "label"
4924+
```
4925+
}];
4926+
4927+
let arguments = (ins CIR_BlockAddrInfoAttr:$block_addr_info);
4928+
let results = (outs CIR_VoidPtrType:$addr);
4929+
let assemblyFormat = [{
4930+
$block_addr_info `:` qualified(type($addr)) attr-dict
4931+
}];
4932+
}
4933+
48484934
#endif // CLANG_CIR_DIALECT_IR_CIROPS_TD

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -781,9 +781,25 @@ struct LibcFunNamePrefixSuffixParser {
781781
}
782782
};
783783

784+
// Constant fold a conditional expression 'cond ? A : B' to
785+
// - 'A', if 'cond' has constant true value;
786+
// - 'B', if 'cond' has constant false value.
787+
static const Expr *tryConstantFoldConditionalExpr(const Expr *E,
788+
const ASTContext &Ctx) {
789+
// FIXME: more places can use this function
790+
if (const auto *CE = dyn_cast<ConditionalOperator>(E)) {
791+
bool CondEval;
792+
793+
if (CE->getCond()->EvaluateAsBooleanCondition(CondEval, Ctx))
794+
return CondEval ? CE->getLHS() : CE->getRHS();
795+
}
796+
return E;
797+
}
798+
784799
// A pointer type expression is known to be null-terminated, if it has the
785800
// form: E.c_str(), for any expression E of `std::string` type.
786-
static bool isNullTermPointer(const Expr *Ptr) {
801+
static bool isNullTermPointer(const Expr *Ptr, ASTContext &Ctx) {
802+
Ptr = tryConstantFoldConditionalExpr(Ptr, Ctx);
787803
if (isa<clang::StringLiteral>(Ptr->IgnoreParenImpCasts()))
788804
return true;
789805
if (isa<PredefinedExpr>(Ptr->IgnoreParenImpCasts()))
@@ -874,7 +890,7 @@ static bool hasUnsafeFormatOrSArg(const CallExpr *Call, const Expr *&UnsafeArg,
874890

875891
const Expr *Arg = Call->getArg(ArgIdx);
876892

877-
if (isNullTermPointer(Arg))
893+
if (isNullTermPointer(Arg, Ctx))
878894
// If Arg is a null-terminated pointer, it is safe anyway.
879895
return true; // continue parsing
880896

@@ -922,8 +938,8 @@ static bool hasUnsafeFormatOrSArg(const CallExpr *Call, const Expr *&UnsafeArg,
922938
// (including the format argument) is unsafe pointer.
923939
return llvm::any_of(
924940
llvm::make_range(Call->arg_begin() + FmtArgIdx, Call->arg_end()),
925-
[&UnsafeArg](const Expr *Arg) -> bool {
926-
if (Arg->getType()->isPointerType() && !isNullTermPointer(Arg)) {
941+
[&UnsafeArg, &Ctx](const Expr *Arg) -> bool {
942+
if (Arg->getType()->isPointerType() && !isNullTermPointer(Arg, Ctx)) {
927943
UnsafeArg = Arg;
928944
return true;
929945
}
@@ -1175,7 +1191,7 @@ static bool hasUnsafePrintfStringArg(const CallExpr &Node, ASTContext &Ctx,
11751191
// We don't really recognize this "normal" printf, the only thing we
11761192
// can do is to require all pointers to be null-terminated:
11771193
for (const auto *Arg : Node.arguments())
1178-
if (Arg->getType()->isPointerType() && !isNullTermPointer(Arg)) {
1194+
if (Arg->getType()->isPointerType() && !isNullTermPointer(Arg, Ctx)) {
11791195
Result.addNode(Tag, DynTypedNode::create(*Arg));
11801196
return true;
11811197
}

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,19 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
405405
return Address(baseAddr, destType, addr.getAlignment());
406406
}
407407

408+
Address createDerivedClassAddr(mlir::Location loc, Address addr,
409+
mlir::Type destType, unsigned offset,
410+
bool assumeNotNull) {
411+
if (destType == addr.getElementType())
412+
return addr;
413+
414+
cir::PointerType ptrTy = getPointerTo(destType);
415+
auto derivedAddr =
416+
cir::DerivedClassAddrOp::create(*this, loc, ptrTy, addr.getPointer(),
417+
mlir::APInt(64, offset), assumeNotNull);
418+
return Address(derivedAddr, destType, addr.getAlignment());
419+
}
420+
408421
mlir::Value createVTTAddrPoint(mlir::Location loc, mlir::Type retTy,
409422
mlir::Value addr, uint64_t offset) {
410423
return cir::VTTAddrPointOp::create(*this, loc, retTy,

0 commit comments

Comments
 (0)