1; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s 2 3; CHECK: Function: t1 4; CHECK: NoAlias: i32* %gep1, i32* %gep2 5define void @t1(ptr %p, i32 %addend, ptr %q) { 6 %knownnonzero = load i32, ptr %q, !range !0 7 %add = add nsw nuw i32 %addend, %knownnonzero 8 %gep1 = getelementptr [8 x i32], ptr %p, i32 2, i32 %addend 9 %gep2 = getelementptr [8 x i32], ptr %p, i32 2, i32 %add 10 load i32, ptr %gep1 11 load i32, ptr %gep2 12 ret void 13} 14 15; CHECK: Function: t2 16; CHECK: MayAlias: i32* %gep1, i32* %gep2 17define void @t2(ptr %p, i32 %addend, ptr %q) { 18 %knownnonzero = load i32, ptr %q, !range !0 19 %add = add nsw nuw i32 %addend, %knownnonzero 20 %gep1 = getelementptr [8 x i32], ptr %p, i32 1, i32 %addend 21 %gep2 = getelementptr [8 x i32], ptr %p, i32 0, i32 %add 22 load i32, ptr %gep1 23 load i32, ptr %gep2 24 ret void 25} 26 27; CHECK: Function: t3 28; CHECK: MustAlias: i32* %gep1, i32* %gep2 29define void @t3(ptr %p, i32 %addend, ptr %q) { 30 %knownnonzero = load i32, ptr %q, !range !0 31 %add = add nsw nuw i32 %addend, %knownnonzero 32 %gep1 = getelementptr [8 x i32], ptr %p, i32 0, i32 %add 33 %gep2 = getelementptr [8 x i32], ptr %p, i32 0, i32 %add 34 load i32, ptr %gep1 35 load i32, ptr %gep2 36 ret void 37} 38 39; CHECK: Function: t4 40; CHECK: MayAlias: i32* %gep1, i32* %gep2 41define void @t4(ptr %p, i32 %addend, ptr %q) { 42 %knownnonzero = load i32, ptr %q, !range !0 43 %add = add nsw nuw i32 %addend, %knownnonzero 44 %gep1 = getelementptr [8 x i32], ptr %p, i32 1, i32 %addend 45 %gep2 = getelementptr [8 x i32], ptr %p, i32 %add, i32 %add 46 load i32, ptr %gep1 47 load i32, ptr %gep2 48 ret void 49} 50 51; CHECK: Function: t5 52; CHECK: MayAlias: i64* %gep1, i32* %gep2 53define void @t5(ptr %p, i32 %addend, ptr %q) { 54 %knownnonzero = load i32, ptr %q, !range !0 55 %add = add nsw nuw i32 %addend, %knownnonzero 56 %gep1 = getelementptr [8 x i32], ptr %p, i32 2, i32 %addend 57 %gep2 = getelementptr [8 x i32], ptr %p, i32 2, i32 %add 58 load i32, ptr %gep2 59 load i64, ptr %gep1 60 ret void 61} 62 63; CHECK-LABEL: Function: add_non_zero_simple 64; CHECK: NoAlias: i32* %gep1, i32* %gep2 65define void @add_non_zero_simple(ptr %p, i32 %addend, ptr %q) { 66 %knownnonzero = load i32, ptr %q, !range !0 67 %add = add i32 %addend, %knownnonzero 68 %gep1 = getelementptr i32, ptr %p, i32 %addend 69 %gep2 = getelementptr i32, ptr %p, i32 %add 70 load i32, ptr %gep1 71 load i32, ptr %gep2 72 ret void 73} 74 75; CHECK-LABEL: Function: add_non_zero_different_scales 76; CHECK: MayAlias: i32* %gep1, i16* %gep2 77define void @add_non_zero_different_scales(ptr %p, i32 %addend, ptr %q) { 78 %knownnonzero = load i32, ptr %q, !range !0 79 %add = add i32 %addend, %knownnonzero 80 %gep1 = getelementptr i32, ptr %p, i32 %addend 81 %gep2 = getelementptr i16, ptr %p, i32 %add 82 load i32, ptr %gep1 83 load i16, ptr %gep2 84 ret void 85} 86 87; CHECK-LABEL: Function: add_non_zero_different_sizes 88; CHECK: NoAlias: i16* %gep1, i32* %gep2 89; CHECK: NoAlias: i32* %gep1, i16* %gep2 90; CHECK: NoAlias: i16* %gep1, i16* %gep2 91; CHECK: MayAlias: i64* %gep1, i32* %gep2 92; CHECK: MayAlias: i64* %gep1, i16* %gep2 93; CHECK: MayAlias: i32* %gep1, i64* %gep2 94; CHECK: MayAlias: i16* %gep1, i64* %gep2 95; CHECK: MayAlias: i64* %gep1, i64* %gep2 96define void @add_non_zero_different_sizes(ptr %p, i32 %addend, ptr %q) { 97 %knownnonzero = load i32, ptr %q, !range !0 98 %add = add i32 %addend, %knownnonzero 99 %gep1 = getelementptr i32, ptr %p, i32 %addend 100 %gep2 = getelementptr i32, ptr %p, i32 %add 101 load i32, ptr %gep1 102 load i32, ptr %gep2 103 load i16, ptr %gep1 104 load i16, ptr %gep2 105 load i64, ptr %gep1 106 load i64, ptr %gep2 107 ret void 108} 109 110 111; CHECK-LABEL: add_non_zero_with_offset 112; MayAlias: ptr %gep1, ptr %gep2 113; NoAlias: ptr %gep1, ptr %gep2 114define void @add_non_zero_with_offset(ptr %p, i32 %addend, ptr %q) { 115 %knownnonzero = load i32, ptr %q, !range !0 116 %add = add i32 %addend, %knownnonzero 117 %p.off.8 = getelementptr i8, ptr %p, i32 2 118 %gep1 = getelementptr i32, ptr %p.off.8, i32 %addend 119 %gep2 = getelementptr i32, ptr %p, i32 %add 120 load i32, ptr %gep1 121 load i32, ptr %gep2 122 load i16, ptr %gep1 123 load i16, ptr %gep2 124 ret void 125} 126 127; CHECK-LABEL: Function: add_non_zero_assume 128; CHECK: NoAlias: i32* %gep1, i32* %gep2 129define void @add_non_zero_assume(ptr %p, i32 %addend, i32 %knownnonzero) { 130 %cmp = icmp ne i32 %knownnonzero, 0 131 call void @llvm.assume(i1 %cmp) 132 %add = add i32 %addend, %knownnonzero 133 %gep1 = getelementptr i32, ptr %p, i32 %addend 134 %gep2 = getelementptr i32, ptr %p, i32 %add 135 load i32, ptr %gep1 136 load i32, ptr %gep2 137 ret void 138} 139 140; CHECK-LABEL: non_zero_index_simple 141; CHECK: NoAlias: i32* %gep, i32* %p 142; CHECK: NoAlias: i16* %gep, i32* %p 143; CHECK: MayAlias: i64* %gep, i32* %p 144define void @non_zero_index_simple(ptr %p, ptr %q) { 145 %knownnonzero = load i32, ptr %q, !range !0 146 %gep = getelementptr i32, ptr %p, i32 %knownnonzero 147 load i32, ptr %p 148 load i32, ptr %gep 149 load i16, ptr %gep 150 load i64, ptr %gep 151 ret void 152} 153 154; CHECK-LABEL: non_zero_index_with_offset 155; CHECK: MayAlias: i32* %gep, i32* %p 156; CHECK: NoAlias: i16* %gep, i32* %p 157define void @non_zero_index_with_offset(ptr %p, ptr %q) { 158 %knownnonzero = load i32, ptr %q, !range !0 159 %p.off.8 = getelementptr i8, ptr %p, i32 2 160 %gep = getelementptr i32, ptr %p.off.8, i32 %knownnonzero 161 load i32, ptr %p 162 load i32, ptr %gep 163 load i16, ptr %gep 164 ret void 165} 166 167; CHECK-LABEL: non_zero_index_assume 168; CHECK: NoAlias: i32* %gep, i32* %p 169define void @non_zero_index_assume(ptr %p, i32 %knownnonzero) { 170 %cmp = icmp ne i32 %knownnonzero, 0 171 call void @llvm.assume(i1 %cmp) 172 %gep = getelementptr i32, ptr %p, i32 %knownnonzero 173 load i32, ptr %p 174 load i32, ptr %gep 175 ret void 176} 177 178declare void @llvm.assume(i1) 179 180!0 = !{ i32 1, i32 0 } 181