llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clangir Author: David Rivera (RiverDave) <details> <summary>Changes</summary> ## Summary - Stamp `llvm.noalias` on function returns when the callee has `RestrictAttr` (`__attribute__((malloc))` / `__declspec(restrict)`) and no deallocator. - Matches classic codegen in `CGCall.cpp`: return `noalias` on both `define` and `call`, and skip `malloc(dealloc)`. - Extends `restrict-noalias.c` with a malloc call, a malloc definition, and a `malloc(dealloc)` negative. ## Test plan - [x] `llvm-lit clang/test/CIR/CodeGen/restrict-noalias.c` - [ ] Pre-merge Clang CIR checks Made with [Cursor](https://cursor.com) --- Full diff: https://github.com/llvm/llvm-project/pull/221817.diff 2 Files Affected: - (modified) clang/lib/CIR/CodeGen/CIRGenCall.cpp (+9-3) - (modified) clang/test/CIR/CodeGen/restrict-noalias.c (+59-3) ``````````diff diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index 3a4b7cecf2e08..db17709050018 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -403,9 +403,6 @@ void CIRGenModule::constructAttributeList( attrs.set(cir::CIRDialect::getSideEffectAttrName(), cir::SideEffectAttr::get(&getMLIRContext(), sideEffect)); - // TODO(cir): Add noalias to returns for malloc-like functions - // (__attribute__((malloc)) / __declspec(restrict)). - if (targetDecl->hasAttr<ReturnsNonNullAttr>() && !codeGenOpts.NullPointerIsValid) retAttrs.set(mlir::LLVM::LLVMDialect::getNonNullAttrName(), @@ -665,6 +662,15 @@ void CIRGenModule::constructFunctionReturnAttributes( getNaturalPointeeTypeAlignment(retTy).getQuantity())); } } + + // __attribute__((malloc)) / __declspec(restrict) -> noalias on the return + // value. Classic skips the attribute when a deallocator is specified + // (malloc(dealloc) / malloc(dealloc, N)). + if (const auto *restrictAttr = + targetDecl ? targetDecl->getAttr<RestrictAttr>() : nullptr; + restrictAttr && restrictAttr->getDeallocator() == nullptr) + retAttrs.set(mlir::LLVM::LLVMDialect::getNoAliasAttrName(), + mlir::UnitAttr::get(&getMLIRContext())); } void CIRGenModule::constructFunctionArgumentAttributes( diff --git a/clang/test/CIR/CodeGen/restrict-noalias.c b/clang/test/CIR/CodeGen/restrict-noalias.c index b69de97b07864..2ad1dc391be9c 100644 --- a/clang/test/CIR/CodeGen/restrict-noalias.c +++ b/clang/test/CIR/CodeGen/restrict-noalias.c @@ -1,8 +1,8 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-ignored-attributes -fclangir -emit-cir %s -o %t.cir // RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-ignored-attributes -fclangir -emit-llvm %s -o %t-cir.ll // RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-ignored-attributes -emit-llvm %s -o %t.ll // RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s void user_func(int *__restrict p); @@ -36,3 +36,59 @@ void test_builtin(const char *__restrict fmt) { // OGCG: define dso_local void @test_builtin(ptr noalias noundef %{{.*}}) // OGCG: call i32 (ptr, ...) @printf(ptr noundef %{{.*}}) + +__attribute__((malloc)) void *my_malloc(unsigned long n); +void *test_ret(unsigned long n) { return my_malloc(n); } + +// CIR: cir.func {{.*}} @test_ret(%{{.*}}: !u64i {llvm.noundef} +// CIR: cir.call @my_malloc(%{{.*}}) : (!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.noalias{{.*}}}) +// CIR: cir.func {{.*}} @my_malloc(!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.noalias{{.*}}}) + +// LLVM: define dso_local {{.*}}ptr @test_ret +// LLVM: call noalias {{.*}}ptr @my_malloc +// LLVM: declare noalias {{.*}}ptr @my_malloc + +// OGCG: define dso_local {{.*}}ptr @test_ret +// OGCG: call noalias {{.*}}ptr @my_malloc +// OGCG: declare noalias {{.*}}ptr @my_malloc + +__attribute__((malloc)) void *my_malloc_def(unsigned long n) { return 0; } + +// CIR: cir.func {{.*}} @my_malloc_def(%{{.*}}: !u64i {llvm.noundef} +// CIR-SAME: -> (!cir.ptr<!void> {llvm.noalias{{.*}}}) + +// LLVM: define dso_local noalias {{.*}}ptr @my_malloc_def +// OGCG: define dso_local noalias {{.*}}ptr @my_malloc_def + +int *Mem; +void dealloc(int *); +__attribute__((malloc(dealloc))) int *malloc_with_dealloc(void) { return Mem; } +__attribute__((malloc(dealloc, 1))) int *malloc_with_dealloc_idx(void) { + return Mem; +} + +int *test_malloc_with_dealloc(void) { return malloc_with_dealloc(); } + +// CIR-LABEL: cir.func {{.*}} @malloc_with_dealloc +// CIR-NOT: llvm.noalias +// CIR-LABEL: cir.func {{.*}} @malloc_with_dealloc_idx +// CIR-NOT: llvm.noalias +// CIR-LABEL: cir.func {{.*}} @test_malloc_with_dealloc +// CIR: cir.call @malloc_with_dealloc() : () -> !cir.ptr<!s32i> +// CIR-NOT: llvm.noalias + +// LLVM: define dso_local {{.*}}ptr @malloc_with_dealloc() +// LLVM-NOT: noalias +// LLVM: define dso_local {{.*}}ptr @malloc_with_dealloc_idx() +// LLVM-NOT: noalias +// LLVM: define dso_local {{.*}}ptr @test_malloc_with_dealloc() +// LLVM: call {{.*}}ptr @malloc_with_dealloc() +// LLVM-NOT: call noalias + +// OGCG: define dso_local {{.*}}ptr @malloc_with_dealloc() +// OGCG-NOT: noalias +// OGCG: define dso_local {{.*}}ptr @malloc_with_dealloc_idx() +// OGCG-NOT: noalias +// OGCG: define dso_local {{.*}}ptr @test_malloc_with_dealloc() +// OGCG: call {{.*}}ptr @malloc_with_dealloc() +// OGCG-NOT: call noalias `````````` </details> https://github.com/llvm/llvm-project/pull/221817 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
