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