[llvm] 3c9e849 - [FunctionAttrs] Add tests for argmemonly inference.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 10 14:32:50 PST 2022


Author: Florian Hahn
Date: 2022-03-10T22:32:29Z
New Revision: 3c9e8499435a4ecd197dcae23e9de6da914057d2

URL: https://github.com/llvm/llvm-project/commit/3c9e8499435a4ecd197dcae23e9de6da914057d2
DIFF: https://github.com/llvm/llvm-project/commit/3c9e8499435a4ecd197dcae23e9de6da914057d2.diff

LOG: [FunctionAttrs] Add tests for argmemonly inference.

Added: 
    llvm/test/Transforms/FunctionAttrs/argmemonly.ll

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/FunctionAttrs/argmemonly.ll b/llvm/test/Transforms/FunctionAttrs/argmemonly.ll
new file mode 100644
index 0000000000000..a0dec5c53bf93
--- /dev/null
+++ b/llvm/test/Transforms/FunctionAttrs/argmemonly.ll
@@ -0,0 +1,192 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes
+; RUN: opt -passes=function-attrs -S %s | FileCheck %s
+
+ at g = global i32 20
+
+define void @test_no_read_or_write() {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn
+; CHECK-LABEL: @test_no_read_or_write(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret void
+;
+entry:
+  ret void
+}
+
+define i32 @test_only_read_arg(i32* %ptr) {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readonly willreturn
+; CHECK-LABEL: @test_only_read_arg(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[L:%.*]] = load i32, i32* [[PTR:%.*]], align 4
+; CHECK-NEXT:    ret i32 [[L]]
+;
+entry:
+  %l = load i32, i32* %ptr
+  ret i32 %l
+}
+
+define i32 @test_read_global() {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readonly willreturn
+; CHECK-LABEL: @test_read_global(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[L:%.*]] = load i32, i32* @g, align 4
+; CHECK-NEXT:    ret i32 [[L]]
+;
+entry:
+  %l = load i32, i32* @g
+  ret i32 %l
+}
+
+define i32 @test_read_loaded_ptr(i32** %ptr) {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readonly willreturn
+; CHECK-LABEL: @test_read_loaded_ptr(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[L:%.*]] = load i32*, i32** [[PTR:%.*]], align 8
+; CHECK-NEXT:    [[L_2:%.*]] = load i32, i32* [[L]], align 4
+; CHECK-NEXT:    ret i32 [[L_2]]
+;
+entry:
+  %l = load i32*, i32** %ptr
+  %l.2 = load i32, i32* %l
+  ret i32 %l.2
+}
+
+define void @test_only_write_arg(i32* %ptr) {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn writeonly
+; CHECK-LABEL: @test_only_write_arg(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    store i32 0, i32* [[PTR:%.*]], align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  store i32 0, i32* %ptr
+  ret void
+}
+
+define void @test_write_global() {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn writeonly
+; CHECK-LABEL: @test_write_global(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    store i32 0, i32* @g, align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  store i32 0, i32* @g
+  ret void
+}
+
+declare void @fn_may_access_memory()
+
+define void @test_call_may_access_memory() {
+; CHECK-LABEL: @test_call_may_access_memory(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    call void @fn_may_access_memory()
+; CHECK-NEXT:    ret void
+;
+entry:
+  call void @fn_may_access_memory()
+  ret void
+}
+
+declare i32 @fn_readnone() readnone
+
+define void @test_call_readnone(i32* %ptr) {
+; CHECK: Function Attrs: writeonly
+; CHECK-LABEL: @test_call_readnone(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C:%.*]] = call i32 @fn_readnone()
+; CHECK-NEXT:    store i32 [[C]], i32* [[PTR:%.*]], align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  %c = call i32 @fn_readnone()
+  store i32 %c, i32* %ptr
+  ret void
+}
+
+declare i32 @fn_argmemonly(i32*) argmemonly
+
+define i32 @test_call_argmemonly(i32* %ptr) {
+; CHECK-LABEL: @test_call_argmemonly(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C:%.*]] = call i32 @fn_argmemonly(i32* [[PTR:%.*]])
+; CHECK-NEXT:    ret i32 [[C]]
+;
+entry:
+  %c = call i32 @fn_argmemonly(i32* %ptr)
+  ret i32 %c
+}
+
+define i32 @test_call_fn_where_argmemonly_can_be_inferred(i32* %ptr) {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readonly willreturn
+; CHECK-LABEL: @test_call_fn_where_argmemonly_can_be_inferred(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C:%.*]] = call i32 @test_only_read_arg(i32* [[PTR:%.*]])
+; CHECK-NEXT:    ret i32 [[C]]
+;
+entry:
+  %c = call i32 @test_only_read_arg(i32* %ptr)
+  ret i32 %c
+}
+
+define void @test_memcpy_argonly(i8* %dst, i8* %src) {
+; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn
+; CHECK-LABEL: @test_memcpy_argonly(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 32, i1 false)
+; CHECK-NEXT:    ret void
+;
+entry:
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 32, i1 false)
+  ret void
+}
+
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)
+
+ at arr = global [32 x i8] zeroinitializer
+
+define void @test_memcpy_src_global(i8* %dst) {
+; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn
+; CHECK-LABEL: @test_memcpy_src_global(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[BC:%.*]] = bitcast [32 x i8]* @arr to i8*
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[BC]], i64 32, i1 false)
+; CHECK-NEXT:    ret void
+;
+entry:
+  %bc = bitcast [32 x i8]* @arr to i8*
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %bc, i64 32, i1 false)
+  ret void
+}
+
+define void @test_memcpy_dst_global(i8* %src) {
+; CHECK: Function Attrs: mustprogress nofree nosync nounwind willreturn
+; CHECK-LABEL: @test_memcpy_dst_global(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[BC:%.*]] = bitcast [32 x i8]* @arr to i8*
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[BC]], i8* [[SRC:%.*]], i64 32, i1 false)
+; CHECK-NEXT:    ret void
+;
+entry:
+  %bc = bitcast [32 x i8]* @arr to i8*
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %bc, i8* %src, i64 32, i1 false)
+  ret void
+}
+
+define i32 @test_read_arg_access_alloca(i32* %ptr) {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readonly willreturn
+; CHECK-LABEL: @test_read_arg_access_alloca(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    [[L:%.*]] = load i32, i32* [[PTR:%.*]], align 4
+; CHECK-NEXT:    store i32 [[L]], i32* [[A]], align 4
+; CHECK-NEXT:    [[L_2:%.*]] = load i32, i32* [[A]], align 4
+; CHECK-NEXT:    ret i32 [[L_2]]
+;
+entry:
+  %a = alloca i32
+  %l = load i32, i32* %ptr
+  store i32 %l, i32* %a
+  %l.2 = load i32, i32* %a
+  ret i32 %l.2
+}


        


More information about the llvm-commits mailing list