1; RUN: opt -basic-aa -print-all-alias-modref-info -aa-eval < %s 2>&1 | FileCheck %s 2 3target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4 5@G = global i32 0, align 4 6 7define i64 @global_and_deref_arg_1(i64* dereferenceable(8) %arg) nofree nosync { 8; CHECK: Function: global_and_deref_arg_1: 2 pointers, 0 call sites 9; CHECK-NEXT: NoAlias: i32* @G, i64* %arg 10bb: 11 store i64 1, i64* %arg, align 8 12 store i32 0, i32* @G, align 4 13 %tmp = load i64, i64* %arg, align 8 14 ret i64 %tmp 15} 16 17define i32 @global_and_deref_arg_2(i32* dereferenceable(8) %arg) nofree nosync { 18; CHECK: Function: global_and_deref_arg_2: 2 pointers, 0 call sites 19; CHECK-NEXT: NoAlias: i32* %arg, i32* @G 20bb: 21 store i32 1, i32* %arg, align 8 22 store i32 0, i32* @G, align 4 23 %tmp = load i32, i32* %arg, align 8 24 ret i32 %tmp 25} 26 27define i32 @byval_and_deref_arg_1(i32* byval(i32) %obj, i64* dereferenceable(8) %arg) nofree nosync { 28; CHECK: Function: byval_and_deref_arg_1: 2 pointers, 0 call sites 29; CHECK-NEXT: NoAlias: i32* %obj, i64* %arg 30bb: 31 store i32 1, i32* %obj, align 4 32 store i64 0, i64* %arg, align 8 33 %tmp = load i32, i32* %obj, align 4 34 ret i32 %tmp 35} 36 37define i32 @byval_and_deref_arg_2(i32* byval(i32) %obj, i32* dereferenceable(8) %arg) nofree nosync { 38; CHECK: Function: byval_and_deref_arg_2: 2 pointers, 0 call sites 39; CHECK-NEXT: NoAlias: i32* %arg, i32* %obj 40bb: 41 store i32 1, i32* %obj, align 4 42 store i32 0, i32* %arg, align 8 43 %tmp = load i32, i32* %obj, align 4 44 ret i32 %tmp 45} 46 47declare dereferenceable(8) i32* @get_i32_deref8() 48declare dereferenceable(8) i64* @get_i64_deref8() 49declare void @unknown(i32*) 50 51define i32 @local_and_deref_ret_1() { 52; CHECK: Function: local_and_deref_ret_1: 2 pointers, 2 call sites 53; CHECK-NEXT: NoAlias: i32* %obj, i64* %ret 54bb: 55 %obj = alloca i32 56 call void @unknown(i32* %obj) 57 %ret = call dereferenceable(8) i64* @get_i64_deref8() 58 store i32 1, i32* %obj, align 4 59 store i64 0, i64* %ret, align 8 60 %tmp = load i32, i32* %obj, align 4 61 ret i32 %tmp 62} 63 64define i32 @local_and_deref_ret_2() { 65; CHECK: Function: local_and_deref_ret_2: 2 pointers, 2 call sites 66; CHECK-NEXT: NoAlias: i32* %obj, i32* %ret 67bb: 68 %obj = alloca i32 69 call void @unknown(i32* %obj) 70 %ret = call dereferenceable(8) i32* @get_i32_deref8() 71 store i32 1, i32* %obj, align 4 72 store i32 0, i32* %ret, align 8 73 %tmp = load i32, i32* %obj, align 4 74 ret i32 %tmp 75} 76 77 78; Baseline tests, same as above but with 2 instead of 8 dereferenceable bytes. 79 80define i64 @global_and_deref_arg_non_deref_1(i64* dereferenceable(2) %arg) nofree nosync { 81; CHECK: Function: global_and_deref_arg_non_deref_1: 2 pointers, 0 call sites 82; CHECK-NEXT: NoAlias: i32* @G, i64* %arg 83bb: 84 store i64 1, i64* %arg, align 8 85 store i32 0, i32* @G, align 4 86 %tmp = load i64, i64* %arg, align 8 87 ret i64 %tmp 88} 89 90define i32 @global_and_deref_arg_non_deref_2(i32* dereferenceable(2) %arg) nofree nosync { 91; CHECK: Function: global_and_deref_arg_non_deref_2: 2 pointers, 0 call sites 92; Different result than above (see @global_and_deref_arg_2). 93; CHECK-NEXT: MayAlias: i32* %arg, i32* @G 94bb: 95 store i32 1, i32* %arg, align 8 96 store i32 0, i32* @G, align 4 97 %tmp = load i32, i32* %arg, align 8 98 ret i32 %tmp 99} 100 101define i32 @byval_and_deref_arg_non_deref_1(i32* byval(i32) %obj, i64* dereferenceable(2) %arg) nofree nosync { 102; CHECK: Function: byval_and_deref_arg_non_deref_1: 2 pointers, 0 call sites 103; CHECK-NEXT: NoAlias: i32* %obj, i64* %arg 104bb: 105 store i32 1, i32* %obj, align 4 106 store i64 0, i64* %arg, align 8 107 %tmp = load i32, i32* %obj, align 4 108 ret i32 %tmp 109} 110 111define i32 @byval_and_deref_arg_non_deref_2(i32* byval(i32) %obj, i32* dereferenceable(2) %arg) nofree nosync { 112; CHECK: Function: byval_and_deref_arg_non_deref_2: 2 pointers, 0 call sites 113; CHECK-NEXT: NoAlias: i32* %arg, i32* %obj 114bb: 115 store i32 1, i32* %obj, align 4 116 store i32 0, i32* %arg, align 8 117 %tmp = load i32, i32* %obj, align 4 118 ret i32 %tmp 119} 120 121declare dereferenceable(2) i32* @get_i32_deref2() 122declare dereferenceable(2) i64* @get_i64_deref2() 123 124define i32 @local_and_deref_ret_non_deref_1() { 125; CHECK: Function: local_and_deref_ret_non_deref_1: 2 pointers, 2 call sites 126; CHECK-NEXT: NoAlias: i32* %obj, i64* %ret 127bb: 128 %obj = alloca i32 129 call void @unknown(i32* %obj) 130 %ret = call dereferenceable(2) i64* @get_i64_deref2() 131 store i32 1, i32* %obj, align 4 132 store i64 0, i64* %ret, align 8 133 %tmp = load i32, i32* %obj, align 4 134 ret i32 %tmp 135} 136 137define i32 @local_and_deref_ret_non_deref_2() { 138; CHECK: Function: local_and_deref_ret_non_deref_2: 2 pointers, 2 call sites 139; Different result than above (see @local_and_deref_ret_2). 140; CHECK-NEXT: MayAlias: i32* %obj, i32* %ret 141bb: 142 %obj = alloca i32 143 call void @unknown(i32* %obj) 144 %ret = call dereferenceable(2) i32* @get_i32_deref2() 145 store i32 1, i32* %obj, align 4 146 store i32 0, i32* %ret, align 8 147 %tmp = load i32, i32* %obj, align 4 148 ret i32 %tmp 149} 150