[clang] [CIR] Match OGCG noalias and memory effects on operator new (PR #221818)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 7 13:04:16 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: David Rivera (RiverDave)
<details>
<summary>Changes</summary>
## Summary
- On sane replaceable `operator new` call sites, emit return `noalias` and `SideEffect::InaccessibleOrErrno`.
- Lower that side effect to `memory(inaccessiblemem: readwrite, errnomem: write)`, matching classic codegen. `-fno-assume-sane-operator-new` drops both.
- Adds `operator-new-noalias.cpp` and updates existing `new*` FileChecks so CIR LLVM matches OGCG.
## Test plan
- [x] `llvm-lit` on the updated `new*` / builtin / coro / IR tests
- [ ] Pre-merge Clang CIR checks
Made with [Cursor](https://cursor.com)
---
Patch is 68.07 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/221818.diff
12 Files Affected:
- (modified) clang/include/clang/CIR/Dialect/IR/CIRAttrs.td (+7-1)
- (modified) clang/lib/CIR/CodeGen/CIRGenCall.cpp (+10-2)
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+22)
- (modified) clang/test/CIR/CodeGen/new-delete-deactivation.cpp (+6-6)
- (modified) clang/test/CIR/CodeGen/new-delete.cpp (+8-8)
- (modified) clang/test/CIR/CodeGen/new.cpp (+44-44)
- (added) clang/test/CIR/CodeGen/operator-new-noalias.cpp (+24)
- (modified) clang/test/CIR/CodeGen/paren-list-agg-init.cpp (+3-3)
- (modified) clang/test/CIR/CodeGenBuiltins/builtin-new-delete.cpp (+5-5)
- (modified) clang/test/CIR/CodeGenCXX/new-array-init.cpp (+19-19)
- (modified) clang/test/CIR/CodeGenCoroutines/coro-task.cpp (+1-1)
- (modified) clang/test/CIR/IR/call.cir (+2)
``````````diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index fa90ceba97115..c10ed46d1497a 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -1875,7 +1875,8 @@ def CIR_SideEffect : CIR_I32EnumAttr<
"SideEffect", "allowed side effects of a function", [
I32EnumAttrCase<"All", 0, "all">,
I32EnumAttrCase<"Pure", 1, "pure">,
- I32EnumAttrCase<"Const", 2, "const">
+ I32EnumAttrCase<"Const", 2, "const">,
+ I32EnumAttrCase<"InaccessibleOrErrno", 3, "inaccessible_or_errno">
]> {
let description = [{
The side effect attribute specifies the possible side effects of a function
@@ -1889,6 +1890,10 @@ def CIR_SideEffect : CIR_I32EnumAttr<
`__attribute__((pure))`.
- const: The function or callee may not read or write data from memory. This
has the same effect as the GNU C/C++ attribute `__attribute__((const))`.
+ - inaccessible_or_errno: The function or callee may only access inaccessible
+ memory and errno. This matches LLVM
+ `memory(inaccessiblemem: readwrite, errnomem: write)` used for sane
+ `operator new` calls.
Examples:
@@ -1896,6 +1901,7 @@ def CIR_SideEffect : CIR_I32EnumAttr<
%2 = cir.call @add(%0, %1) : (!s32i, !s32i) -> !s32i
%2 = cir.call @add(%0, %1) : (!s32i, !s32i) -> !s32i side_effect(pure)
%2 = cir.call @add(%0, %1) : (!s32i, !s32i) -> !s32i side_effect(const)
+ %2 = cir.call @alloc(%0) : (!u64i) -> !cir.ptr<!void> side_effect(inaccessible_or_errno)
```
}];
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index 3a4b7cecf2e08..33dd3205a4bd1 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -372,8 +372,16 @@ void CIRGenModule::constructAttributeList(
addAttributesFromFunctionProtoType(
getBuilder(), attrs, func->getType()->getAs<FunctionProtoType>());
- // TODO(cir): When doing 'return attrs' we need to cover the 'NoAlias' for
- // global allocation functions here.
+ // A sane operator new returns a non-aliasing pointer and does not read
+ // or write accessible memory. Classic applies this only at call sites.
+ if (attrOnCallSite && func->isReplaceableGlobalAllocationFunction() &&
+ codeGenOpts.AssumeSaneOperatorNew &&
+ func->getDeclName().isAnyOperatorNew()) {
+ retAttrs.set(mlir::LLVM::LLVMDialect::getNoAliasAttrName(),
+ mlir::UnitAttr::get(&getMLIRContext()));
+ sideEffect = cir::SideEffect::InaccessibleOrErrno;
+ }
+
assert(!cir::MissingFeatures::opCallAttrs());
const CXXMethodDecl *md = dyn_cast<CXXMethodDecl>(func);
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 6f7509c363fd3..156f44d5b5296 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -457,6 +457,18 @@ void convertSideEffectForCall(mlir::Operation *callOp, bool isNothrow,
noUnwind = true;
willReturn = true;
break;
+
+ case cir::SideEffect::InaccessibleOrErrno:
+ memoryEffect = mlir::LLVM::MemoryEffectsAttr::get(
+ callOp->getContext(), /*other=*/ModRefInfo::NoModRef,
+ /*argMem=*/ModRefInfo::NoModRef,
+ /*inaccessibleMem=*/ModRefInfo::ModRef,
+ /*errnoMem=*/ModRefInfo::Mod,
+ /*targetMem0=*/ModRefInfo::NoModRef,
+ /*targetMem1=*/ModRefInfo::NoModRef);
+ noUnwind = isNothrow;
+ willReturn = false;
+ break;
}
noReturn = callOp->hasAttr(CIRDialect::getNoReturnAttrName());
@@ -2824,6 +2836,16 @@ mlir::LogicalResult CIRToLLVMFuncOpLowering::matchAndRewrite(
fn.setNoUnwind(true);
fn.setWillReturn(true);
break;
+ case cir::SideEffect::InaccessibleOrErrno:
+ fn.setMemoryEffectsAttr(mlir::LLVM::MemoryEffectsAttr::get(
+ fn.getContext(),
+ /*other=*/mlir::LLVM::ModRefInfo::NoModRef,
+ /*argMem=*/mlir::LLVM::ModRefInfo::NoModRef,
+ /*inaccessibleMem=*/mlir::LLVM::ModRefInfo::ModRef,
+ /*errnoMem=*/mlir::LLVM::ModRefInfo::Mod,
+ /*targetMem0=*/mlir::LLVM::ModRefInfo::NoModRef,
+ /*targetMem1=*/mlir::LLVM::ModRefInfo::NoModRef));
+ break;
}
}
diff --git a/clang/test/CIR/CodeGen/new-delete-deactivation.cpp b/clang/test/CIR/CodeGen/new-delete-deactivation.cpp
index 050dd9abf413a..20b0221812cab 100644
--- a/clang/test/CIR/CodeGen/new-delete-deactivation.cpp
+++ b/clang/test/CIR/CodeGen/new-delete-deactivation.cpp
@@ -49,7 +49,7 @@ A *deact_simple() { return new A(makeB()); }
// LLVM-LABEL: define dso_local ptr @_Z12deact_simplev() {{.*}} personality ptr @__gxx_personality_v0 {
// LLVM: %[[TMP:.*]] = alloca %struct.B
// LLVM: %[[ACTIVE:.*]] = alloca i8
-// LLVM: %[[PTR:.*]] = call nonnull ptr @_Znwm(i64 1) #[[ATTR_BUILTIN_NEW:.*]]
+// LLVM: %[[PTR:.*]] = call noalias nonnull ptr @_Znwm(i64 1) #[[ATTR_BUILTIN_NEW:.*]]
// LLVM: store i8 1, ptr %[[ACTIVE]]
// LLVM: invoke void @_Z5makeBv(ptr dead_on_unwind writable sret(%struct.B) align 4 %[[TMP]])
// LLVM: to label %[[INVOKE_CONT:.*]] unwind label %[[UNWIND_OUTER:.*]]
@@ -124,7 +124,7 @@ A *deact_if(bool cond) {
// LLVM-LABEL: define dso_local ptr @_Z8deact_ifb(i1 zeroext %0) {{.*}} personality ptr @__gxx_personality_v0 {
// LLVM: br i1 %{{.*}}, label %[[THEN:.*]], label %[[END:.*]]
// LLVM: [[THEN]]:
-// LLVM: %[[PTR:.*]] = call nonnull ptr @_Znwm(i64 1) #[[ATTR_BUILTIN_NEW]]
+// LLVM: %[[PTR:.*]] = call noalias nonnull ptr @_Znwm(i64 1) #[[ATTR_BUILTIN_NEW]]
// LLVM: store i8 1, ptr %[[ACTIVE:.*]]
// LLVM: invoke void @_ZN1AC1Ei(ptr {{.*}} %[[PTR]], i32 {{.*}})
// LLVM: to label %[[CONT:.*]] unwind label %[[UNWIND_INNER:.*]]
@@ -177,7 +177,7 @@ A *deact_ternary(bool cond) { return (new A(makeB()), cond) ? nullptr : nullptr;
// CIR: }
// LLVM-LABEL: define dso_local ptr @_Z13deact_ternaryb(i1 zeroext %0) {{.*}} personality ptr @__gxx_personality_v0 {
-// LLVM: %[[PTR:.*]] = call nonnull ptr @_Znwm(i64 1) #[[ATTR_BUILTIN_NEW]]
+// LLVM: %[[PTR:.*]] = call noalias nonnull ptr @_Znwm(i64 1) #[[ATTR_BUILTIN_NEW]]
// LLVM: store i8 1, ptr %[[ACTIVE:.*]]
// LLVM: invoke void @_ZN1AC1Ei(ptr {{.*}} %[[PTR]], i32 {{.*}})
// LLVM: to label %[[CONT:.*]] unwind label %[[UNWIND_INNER:.*]]
@@ -240,7 +240,7 @@ A *deact_while_cond(int n) {
// LLVM: %[[ACTIVE:.*]] = alloca i8
// LLVM: br label %[[WHILE_COND:.*]]
// LLVM: [[WHILE_COND]]:
-// LLVM: %[[PTR:.*]] = call nonnull ptr @_Znwm(i64 1) #[[ATTR_BUILTIN_NEW]]
+// LLVM: %[[PTR:.*]] = call noalias nonnull ptr @_Znwm(i64 1) #[[ATTR_BUILTIN_NEW]]
// LLVM: store i8 1, ptr %[[ACTIVE]]
// LLVM: invoke void @_Z5makeBv(ptr dead_on_unwind writable sret(%struct.B) align 4 %[[TMP]])
// LLVM: to label %[[INVOKE_CONT:.*]] unwind label %[[UNWIND_OUTER:.*]]
@@ -320,7 +320,7 @@ A *deact_switch(int kind) {
// LLVM: i32 1, label %[[CASE1:.*]]
// LLVM: ]
// LLVM: [[CASE1]]:
-// LLVM: %[[PTR:.*]] = call nonnull ptr @_Znwm(i64 1) #[[ATTR_BUILTIN_NEW]]
+// LLVM: %[[PTR:.*]] = call noalias nonnull ptr @_Znwm(i64 1) #[[ATTR_BUILTIN_NEW]]
// LLVM: store i8 1, ptr %[[ACTIVE:.*]]
// LLVM: invoke void @_ZN1AC1Ei(ptr {{.*}} %[[PTR]], i32 {{.*}})
// LLVM: to label %[[CONT:.*]] unwind label %[[UNWIND_INNER:.*]]
@@ -358,7 +358,7 @@ A *deact_switch(int kind) {
// OGCG: [[DO_DELETE]]:
// OGCG: call void @_ZdlPv(ptr %[[PTR]])
-// LLVM-DAG: attributes #[[ATTR_BUILTIN_NEW]] = {{{.*}}builtin{{.*}}}
+// LLVM-DAG: attributes #[[ATTR_BUILTIN_NEW]] = {{{.*}}builtin{{.*}}memory(inaccessiblemem: readwrite, errnomem: write){{.*}}}
// LLVM-DAG: attributes #[[ATTR_BUILTIN_DEL]] = {{{.*}}builtin{{.*}}}
// LLVM-DAG: attributes #[[ATTR_NOUNWIND]] = {{{.*}}nounwind{{.*}}}
// OGCG-DAG: attributes #[[OGCG_ATTR_BUILTIN_NEW]] = {{{.*}}builtin{{.*}}}
diff --git a/clang/test/CIR/CodeGen/new-delete.cpp b/clang/test/CIR/CodeGen/new-delete.cpp
index fb60110925c71..35700892e7b6d 100644
--- a/clang/test/CIR/CodeGen/new-delete.cpp
+++ b/clang/test/CIR/CodeGen/new-delete.cpp
@@ -16,7 +16,7 @@ A *a() {
// CIR: %[[RETVAL:.*]] = cir.alloca "__retval" {{.*}} : !cir.ptr<!cir.ptr<!rec_A>>
// CIR: %[[NEW_RESULT:.*]] = cir.alloca "__new_result" {{.*}} : !cir.ptr<!cir.ptr<!rec_A>>
// CIR: %[[ALLOC_SIZE:.*]] = cir.const #cir.int<8> : !u64i
-// CIR: %[[PTR:.*]] = cir.call @_Znwm(%[[ALLOC_SIZE]]) {{{.*}}builtin}
+// CIR: %[[PTR:.*]] = cir.call @_Znwm(%[[ALLOC_SIZE]]) side_effect(inaccessible_or_errno) {{{.*}}builtin}
// CIR: cir.cleanup.scope {
// CIR: %[[PTR_A:.*]] = cir.cast bitcast %[[PTR]] : !cir.ptr<!void> -> !cir.ptr<!rec_A>
// CIR: cir.store{{.*}} %[[PTR_A]], %[[NEW_RESULT]] : !cir.ptr<!rec_A>, !cir.ptr<!cir.ptr<!rec_A>>
@@ -31,7 +31,7 @@ A *a() {
// LLVM: define {{.*}} ptr @_Z1av() {{.*}} personality ptr @__gxx_personality_v0 {
// LLVM: %[[RETVAL:.*]] = alloca ptr
// LLVM: %[[NEW_RESULT:.*]] = alloca ptr
-// LLVM: %[[PTR:.*]] = call nonnull ptr @_Znwm(i64 8) #[[ATTR_BUILTIN_NEW:.*]]
+// LLVM: %[[PTR:.*]] = call noalias nonnull ptr @_Znwm(i64 8) #[[ATTR_BUILTIN_NEW:.*]]
// LLVM: br label %[[EH_SCOPE:.*]]
// LLVM: [[EH_SCOPE]]:
// LLVM: store ptr %[[PTR]], ptr %[[NEW_RESULT]]
@@ -91,7 +91,7 @@ A *b() {
// CIR: %[[RETVAL:.*]] = cir.alloca "__retval" {{.*}} : !cir.ptr<!cir.ptr<!rec_A>>
// CIR: %[[NEW_RESULT:.*]] = cir.alloca "__new_result" {{.*}} : !cir.ptr<!cir.ptr<!rec_A>>
// CIR: %[[ALLOC_SIZE:.*]] = cir.const #cir.int<8> : !u64i
-// CIR: %[[PTR:.*]] = cir.call @_Znwm(%[[ALLOC_SIZE]]) {{{.*}}builtin}
+// CIR: %[[PTR:.*]] = cir.call @_Znwm(%[[ALLOC_SIZE]]) side_effect(inaccessible_or_errno) {{{.*}}builtin}
// CIR: cir.cleanup.scope {
// CIR: %[[PTR_A:.*]] = cir.cast bitcast %[[PTR]] : !cir.ptr<!void> -> !cir.ptr<!rec_A>
// CIR: cir.store{{.*}} %[[PTR_A]], %[[NEW_RESULT]] : !cir.ptr<!rec_A>, !cir.ptr<!cir.ptr<!rec_A>>
@@ -106,7 +106,7 @@ A *b() {
// LLVM: define {{.*}} ptr @_Z1bv() {{.*}} personality ptr @__gxx_personality_v0 {
// LLVM: %[[RETVAL:.*]] = alloca ptr
// LLVM: %[[NEW_RESULT:.*]] = alloca ptr
-// LLVM: %[[PTR:.*]] = call nonnull ptr @_Znwm(i64 8) #[[ATTR_BUILTIN_NEW]]
+// LLVM: %[[PTR:.*]] = call noalias nonnull ptr @_Znwm(i64 8) #[[ATTR_BUILTIN_NEW]]
// LLVM: br label %[[EH_SCOPE:.*]]
// LLVM: [[EH_SCOPE]]:
// LLVM: store ptr %[[PTR]], ptr %[[NEW_RESULT]]
@@ -294,7 +294,7 @@ C *test_new_delete_conditional(bool cond) {
// LLVM: store i8 0, ptr %[[CLEANUP_FLAG:.*]], align 1
// LLVM: br i1 {{.*}}, label %[[TRUE_BB:.*]], label %[[FALSE_BB:.*]]
// LLVM: [[TRUE_BB]]:
-// LLVM: %[[NEWP:.*]] = call nonnull ptr @_Znwm(i64 1) #[[ATTR_BUILTIN_NEW]]
+// LLVM: %[[NEWP:.*]] = call noalias nonnull ptr @_Znwm(i64 1) #[[ATTR_BUILTIN_NEW]]
// LLVM: store ptr %[[NEWP]], ptr %[[SAVE_PTR:.*]], align 8
// LLVM: store i8 1, ptr %[[CLEANUP_FLAG]], align 1
// LLVM: invoke void @_ZN1CC1Ev(ptr {{.*}}%[[NEWP]])
@@ -459,7 +459,7 @@ D *test_new_delete_conditional_with_size(bool cond) {
// LLVM: store i8 0, ptr %[[SD_FLAG:.*]], align 1
// LLVM: br i1 {{.*}}, label %[[SD_TRUE:.*]], label %[[SD_FALSE:.*]]
// LLVM: [[SD_TRUE]]:
-// LLVM: %[[SD_NEWP:.*]] = call nonnull ptr @_Znwm(i64 1)
+// LLVM: %[[SD_NEWP:.*]] = call noalias nonnull ptr @_Znwm(i64 1)
// LLVM: store ptr %[[SD_NEWP]], ptr %[[SD_SAVE_PTR:.*]], align 8
// LLVM: store i64 1, ptr %[[SD_SAVE_SIZE:.*]], align 8
// LLVM: store i8 1, ptr %[[SD_FLAG]], align 1
@@ -538,7 +538,7 @@ D *test_new_delete_conditional_array(bool cond, int n) {
// LLVM: br i1 {{.*}}, label %[[ARR_TRUE:.*]], label %[[ARR_FALSE:.*]]
// LLVM: [[ARR_TRUE]]:
// LLVM: %[[ARR_ALLOC_SIZE:.*]] = select i1 %{{.*}}, i64 -1, i64 %{{.*}}
-// LLVM: %[[ARR_NEWP:.*]] = call nonnull ptr @_Znam(i64 %[[ARR_ALLOC_SIZE]])
+// LLVM: %[[ARR_NEWP:.*]] = call noalias nonnull ptr @_Znam(i64 %[[ARR_ALLOC_SIZE]])
// LLVM: store ptr %[[ARR_NEWP]], ptr %[[ARR_SAVE_PTR:.*]], align 8
// LLVM: store i64 %[[ARR_ALLOC_SIZE]], ptr %[[ARR_SAVE_SIZE:.*]], align 8
// LLVM: store i8 1, ptr %[[ARR_FLAG]], align 1
@@ -573,7 +573,7 @@ D *test_new_delete_conditional_array(bool cond, int n) {
// OGCG: %[[OGA_LOAD_SIZE:.*]] = load i64, ptr %[[OGA_SAVE_SIZE]], align 8
// OGCG: invoke void @_ZN1DdaEPvm(ptr %[[OGA_LOAD_PTR]], i64 %[[OGA_LOAD_SIZE]])
-// LLVM-DAG: attributes #[[ATTR_BUILTIN_NEW]] = {{{.*}}builtin{{.*}}}
+// LLVM-DAG: attributes #[[ATTR_BUILTIN_NEW]] = {{{.*}}builtin{{.*}}memory(inaccessiblemem: readwrite, errnomem: write){{.*}}}
// LLVM-DAG: attributes #[[ATTR_BUILTIN_DEL]] = {{{.*}}builtin{{.*}}}
// OGCG-DAG: attributes #[[OGCG_ATTR_BUILTIN_NEW]] = {{{.*}}builtin{{.*}}}
// OGCG-DAG: attributes #[[OGCG_ATTR_BUILTIN_DEL]] = {{{.*}}builtin{{.*}}}
diff --git a/clang/test/CIR/CodeGen/new.cpp b/clang/test/CIR/CodeGen/new.cpp
index 439e1d439c883..0adbfbe72f8d8 100644
--- a/clang/test/CIR/CodeGen/new.cpp
+++ b/clang/test/CIR/CodeGen/new.cpp
@@ -163,7 +163,7 @@ void test_new_with_complex_type() {
// CHECK: cir.func{{.*}} @_Z26test_new_with_complex_typev
// CHECK: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} init : !cir.ptr<!cir.ptr<!cir.complex<!cir.float>>>
// CHECK: %[[COMPLEX_SIZE:.*]] = cir.const #cir.int<8> : !u64i
-// CHECK: %[[NEW_COMPLEX:.*]] = cir.call @_Znwm(%[[COMPLEX_SIZE]]) {allocsize = array<i32: 0>, builtin} : (!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.nonnull, llvm.noundef})
+// CHECK: %[[NEW_COMPLEX:.*]] = cir.call @_Znwm(%[[COMPLEX_SIZE]]) side_effect(inaccessible_or_errno) {allocsize = array<i32: 0>, builtin} : (!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.noalias, llvm.nonnull, llvm.noundef})
// CHECK: %[[COMPLEX_PTR:.*]] = cir.cast bitcast %[[NEW_COMPLEX]] : !cir.ptr<!void> -> !cir.ptr<!cir.complex<!cir.float>>
// CHECK: %[[COMPLEX_VAL:.*]] = cir.const #cir.const_complex<#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> : !cir.float> : !cir.complex<!cir.float>
// CHECK: cir.store{{.*}} %[[COMPLEX_VAL]], %[[COMPLEX_PTR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
@@ -171,7 +171,7 @@ void test_new_with_complex_type() {
// LLVM: define{{.*}} void @_Z26test_new_with_complex_typev
// LLVM: %[[A_ADDR:.*]] = alloca ptr, align 8
-// LLVM: %[[NEW_COMPLEX:.*]] = call noundef nonnull ptr @_Znwm(i64 noundef 8)
+// LLVM: %[[NEW_COMPLEX:.*]] = call noalias noundef nonnull ptr @_Znwm(i64 noundef 8)
// LLVM: store { float, float } { float 1.000000e+00, float 2.000000e+00 }, ptr %[[NEW_COMPLEX]], align 8
// LLVM: store ptr %[[NEW_COMPLEX]], ptr %[[A_ADDR]], align 8
@@ -191,7 +191,7 @@ void t_new_constant_size() {
// CHECK: cir.func{{.*}} @_Z19t_new_constant_sizev()
// CHECK: %[[P_ADDR:.*]] = cir.alloca "p" align(8) init : !cir.ptr<!cir.ptr<!cir.double>>
// CHECK: %[[ALLOCATION_SIZE:.*]] = cir.const #cir.int<128> : !u64i
-// CHECK: %[[RAW_PTR:.*]] = cir.call @_Znam(%[[ALLOCATION_SIZE]]) {allocsize = array<i32: 0>, builtin} : (!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.nonnull, llvm.noundef})
+// CHECK: %[[RAW_PTR:.*]] = cir.call @_Znam(%[[ALLOCATION_SIZE]]) side_effect(inaccessible_or_errno) {allocsize = array<i32: 0>, builtin} : (!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.noalias, llvm.nonnull, llvm.noundef})
// CHECK: %[[TYPED_PTR:.*]] = cir.cast bitcast %[[RAW_PTR]] : !cir.ptr<!void> -> !cir.ptr<!cir.double>
// CHECK: cir.store align(8) %[[TYPED_PTR]], %[[P_ADDR]] : !cir.ptr<!cir.double>, !cir.ptr<!cir.ptr<!cir.double>>
// CHECK: cir.return
@@ -199,7 +199,7 @@ void t_new_constant_size() {
// LLVM: define{{.*}} void @_Z19t_new_constant_sizev
// LLVM: %[[P_ADDR:.*]] = alloca ptr, align 8
-// LLVM: %[[CALL:.*]] = call noundef nonnull ptr @_Znam(i64 noundef 128)
+// LLVM: %[[CALL:.*]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 128)
// LLVM: store ptr %[[CALL]], ptr %[[P_ADDR]], align 8
// OGCG: define{{.*}} void @_Z19t_new_constant_sizev
@@ -220,7 +220,7 @@ void t_constant_size_nontrivial() {
// CHECK: %[[P_ADDR:.*]] = cir.alloca "p" align(8) init : !cir.ptr<!cir.ptr<!rec_C>>
// CHECK: %[[NUM_ELEMENTS:.*]] = cir.const #cir.int<3> : !u64i
// CHECK: %[[ALLOCATION_SIZE:.*]] = cir.const #cir.int<11> : !u64i
-// CHECK: %[[RAW_PTR:.*]] = cir.call @_Znam(%[[ALLOCATION_SIZE]]) {allocsize = array<i32: 0>, builtin} : (!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.nonnull, llvm.noundef})
+// CHECK: %[[RAW_PTR:.*]] = cir.call @_Znam(%[[ALLOCATION_SIZE]]) side_effect(inaccessible_or_errno) {allocsize = array<i32: 0>, builtin} : (!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.noalias, llvm.nonnull, llvm.noundef})
// CHECK: %[[COOKIE_PTR_BASE:.*]] = cir.cast bitcast %[[RAW_PTR]] : !cir.ptr<!void> -> !cir.ptr<!u8i>
// CHECK: %[[COOKIE_PTR:.*]] = cir.cast bitcast %[[COOKIE_PTR_BASE]] : !cir.ptr<!u8i> -> !cir.ptr<!u64i>
// CHECK: cir.store align(8) %[[NUM_ELEMENTS]], %[[COOKIE_PTR]] : !u64i, !cir.ptr<!u64i>
@@ -234,7 +234,7 @@ void t_constant_size_nontrivial() {
// LLVM: @_Z26t_constant_size_nontrivialv()
// LLVM: %[[ALLOCA:.*]] = alloca ptr, align 8
-// LLVM: %[[COOKIE_PTR:.*]] = call noundef nonnull ptr @_Znam(i64 noundef 11)
+// LLVM: %[[COOKIE_PTR:.*]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 11)
// LLVM: store i64 3, ptr %[[COOKIE_PTR]], align 8
// LLVM: %[[ALLOCATED_PTR:.*]] = getelementptr i8, ptr %[[COOKIE_PTR]], i64 8
// LLVM: store ptr %[[ALLOCATED_PTR]], ptr %[[ALLOCA]], align 8
@@ -260,7 +260,7 @@ void t_constant_size_nontrivial2() {
// CHECK: %[[P_ADDR:.*]] = cir.alloca "p" align(8) init : !cir.ptr<!cir.ptr<!rec_D>>
// CHECK: %[[NUM_ELEMENTS:.*]] = cir.const #cir.int<3> : !u64i
// CHECK: %[[ALLOCATION_SIZE:.*]] = cir.const #cir.int<20> : !u64i
-// CHECK: %[[RAW_PTR:.*]] = cir.call @_Znam(%[[ALLOCATION_SIZE]]) {allocsize = array<i32: 0>, builtin} : (!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.nonnull, llvm.noundef})
+// CHECK: %[[RAW_PTR:.*]] = cir.call @_Znam(%[[ALLOCATION_SIZE]]) side_effect(inaccessible_or_errno) {allocsize = array<i32: 0>, builtin} : (!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.noalias, llvm.nonnull, llvm.noundef})
// CHECK: %[[COOKIE_PTR_BASE:.*]] = cir.cast bitcast %[[RAW_PTR]] : !cir.ptr<!void> -> !cir.ptr<!u8i>
// CHECK: %[[COOKIE_PTR:.*]] = cir.cast bitcast %[[COOKIE_PTR_BASE]] : !cir.ptr<!u8i> -> !cir.ptr<!u64i>
// CHECK: cir.store align(8) %[[NUM_ELEMENTS]], %[[COOKIE_PTR]] : !u64i, !cir.ptr<!u64i>
@@ -274,7 +274,7 @@ void t_constant_size_nontrivial2() {
// LLVM: @_Z27t_constant_size_nontrivial2v()
// LLVM: %[[ALLOCA:.*]] = alloca ptr, align 8
-// LLVM: %[[COOKIE_PTR:.*]] = call noundef nonnull ptr @_Znam(i64 noundef 20)
+// LLVM: %[[COOKIE_PTR:.*]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 20)
// LLVM: store i64 3, ptr %[[COOKIE_PTR]], align 8
// LLVM: %[[ALLOCATED_PTR:.*]] = getelementptr i8, ptr %[[COOKIE_PTR]], i64 8
// LLVM: store ptr %[[ALLOCATED_PTR]], ptr %[[ALLOCA]], align 8
@@ -292,7 +292,7 @@ void t_align16_nontrivial() {
// CHECK: %[[P_ADDR:.*]] = cir.alloca "p" align(8) init : !cir.ptr<!cir.ptr<!rec_E>>
// CHECK: %[[NUM_ELEMENTS:.*]] = cir.const #cir.int<2> : !u64i
// CHECK: %[[ALLOCATION_SIZE:.*]] = cir.const #cir.int<48> : !u64i
-// CHECK: %[[RAW_PTR:.*]] = cir.call @_Znam(%[[ALLOCATION_SIZE]]) {allocsize = array<i32: 0>, builtin} : (!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.nonnull, llvm.noundef})
+// CHECK: %[[RAW_PTR:.*]] = cir.call @_Znam(%[[ALLOCATION_SIZE]]) side_effect(inaccessible_or_errno) {allocsize = array<i32: 0>, builtin} : (!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.noalias, llvm.nonnull, llvm.noundef})
// CHECK: %[[COOKIE_PTR_BASE:.*]] = cir.cast bitcast %[[RAW_PTR]] : !cir.ptr<!void> -> !cir.ptr<!u8i>
// CHECK: %[[COOKIE_OFFSET:.*]] = cir.const #cir.int<8> : !s32i
// CHECK: %[[COOKIE_PTR_RAW:.*]] = cir.ptr_stride %[[COOKIE_PTR_BASE]], %[[COOKIE_OFFSET]] : (!cir.ptr<!u8i>, !s32i) -> !cir.ptr<!u8i>
@@ -308,7 +308,7 @@ void t_align16_nontrivial() {
// LLVM: @_Z20t_align16_nontrivialv()
// LLVM: %[[ALLOCA:.*]] = alloca ptr, align 8
-// LLVM: %[[RAW_PTR:.*]] = call noundef nonnull ptr @_Znam(i64 noundef 48)
+// LLVM: %[[...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/221818
More information about the cfe-commits
mailing list