1; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s 2target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" 3target triple = "thumbv7--linux-gnueabi" 4 5; CHECK-LABEL: test_zext_sext_amounts255 6; CHECK: NoAlias: i8* %a, i8* %b 7define void @test_zext_sext_amounts255(ptr %mem) { 8 %sext.1 = sext i8 255 to i16 9 %sext.zext.1 = zext i16 %sext.1 to i64 10 %sext.2 = sext i8 255 to i32 11 %sext.zext.2 = zext i32 %sext.2 to i64 12 %a = getelementptr inbounds i8, ptr %mem, i64 %sext.zext.1 13 %b = getelementptr inbounds i8, ptr %mem, i64 %sext.zext.2 14 load i8, ptr %a 15 load i8, ptr %b 16 ret void 17} 18 19; CHECK-LABEL: test_zext_sext_amounts 20; CHECK: MayAlias: i8* %a, i8* %b 21; %a and %b only PartialAlias as, although they're both zext(sext(%num)) they'll extend the sign by a different 22; number of bits before zext-ing the remainder. 23define void @test_zext_sext_amounts(ptr %mem, i8 %num) { 24 %sext.1 = sext i8 %num to i16 25 %sext.zext.1 = zext i16 %sext.1 to i64 26 %sext.2 = sext i8 %num to i32 27 %sext.zext.2 = zext i32 %sext.2 to i64 28 %a = getelementptr inbounds i8, ptr %mem, i64 %sext.zext.1 29 %b = getelementptr inbounds i8, ptr %mem, i64 %sext.zext.2 30 load i8, ptr %a 31 load i8, ptr %b 32 ret void 33} 34 35; CHECK-LABEL: based_on_pr18068 36; CHECK: NoAlias: i8* %a, i8* %b 37; CHECK: NoAlias: i8* %a, i8* %c 38define void @based_on_pr18068(i32 %loaded, ptr %mem) { 39 %loaded.64 = zext i32 %loaded to i64 40 %add1 = add i32 %loaded, -1 ; unsigned wraps unless %loaded == 0 41 %add1.64 = zext i32 %add1 to i64 ; is zext(%loaded) always != zext(%loaded - 1)? Yes -> NoAlias 42 %sub1 = sub i32 %loaded, 1 ; unsigned wraps iff %loaded == 0 43 %sub1.64 = zext i32 %sub1 to i64 ; is zext(%loaded) always != zext(%loaded - 1)? Yes -> NoAlias 44 %a = getelementptr inbounds i8, ptr %mem, i64 %loaded.64 45 %b = getelementptr inbounds i8, ptr %mem, i64 %add1.64 46 %c = getelementptr inbounds i8, ptr %mem, i64 %sub1.64 47 load i8, ptr %a 48 load i8, ptr %b 49 load i8, ptr %c 50 ret void 51} 52 53; CHECK-LABEL: test_path_dependence 54; CHECK: MayAlias: i8* %a, i8* %b 55; CHECK: MustAlias: i8* %a, i8* %c 56; CHECK: MayAlias: i8* %a, i8* %d 57define void @test_path_dependence(i16 %p, ptr %mem) { 58 %p.minus1 = add i16 %p, -1 ; this will always unsigned-wrap, unless %p == 0 59 %p.minus1.64 = zext i16 %p.minus1 to i64 60 %p.64.again = add i64 %p.minus1.64, 1 ; either %p (if we wrapped) or 65536 (if we didn't) 61 62 %p.nsw.nuw.minus1 = sub nsw nuw i16 %p, 1 ; as nuw we know %p >= 1, and as nsw %p <= 32767 63 %p.nsw.nuw.minus1.64 = zext i16 %p.nsw.nuw.minus1 to i64 64 %p.nsw.nuw.64.again = add nsw nuw i64 %p.nsw.nuw.minus1.64, 1 ; ...so always exactly %p 65 66 %p.nsw.minus1 = sub nsw i16 %p, 1 ; only nsw, so can only guarantee %p != 0x1000 67 %p.nsw.minus1.64 = zext i16 %p.nsw.minus1 to i64 ; when %p > 0x1000 (ie <= 0 as a signed number) then the zext will make this a huge positive number 68 %p.nsw.64.again = add nsw i64 %p.nsw.minus1.64, 1 ; ...and so this is very much != %p 69 70 %p.64 = zext i16 %p to i64 71 %a = getelementptr inbounds i8, ptr %mem, i64 %p.64 72 %b = getelementptr inbounds i8, ptr %mem, i64 %p.64.again 73 %c = getelementptr inbounds i8, ptr %mem, i64 %p.nsw.nuw.64.again 74 %d = getelementptr inbounds i8, ptr %mem, i64 %p.nsw.64.again 75 load i8, ptr %a 76 load i8, ptr %b 77 load i8, ptr %c 78 load i8, ptr %d 79 ret void 80} 81 82; CHECK-LABEL: test_zext_sext_255 83; CHECK: NoAlias: i8* %a, i8* %b 84define void @test_zext_sext_255(ptr %mem) { 85 %zext.255 = zext i8 255 to i16 ; 0x00FF 86 %sext.255 = sext i8 255 to i16 ; 0xFFFF 87 %zext.sext.255 = zext i16 %sext.255 to i32 ; 0x0000FFFF 88 %sext.zext.255 = sext i16 %zext.255 to i32 ; 0x000000FF 89 %zext.zext.sext.255 = zext i32 %zext.sext.255 to i64 90 %zext.sext.zext.255 = zext i32 %sext.zext.255 to i64 91 %a = getelementptr inbounds i8, ptr %mem, i64 %zext.zext.sext.255 92 %b = getelementptr inbounds i8, ptr %mem, i64 %zext.sext.zext.255 93 load i8, ptr %a 94 load i8, ptr %b 95 ret void 96} 97 98; CHECK-LABEL: test_zext_sext_num 99; CHECK: MayAlias: i8* %a, i8* %b 100; %a and %b NoAlias if %num == 255 (see @test_zext_sext_255), but %a and %b NoAlias for other values of %num (e.g. 0) 101define void @test_zext_sext_num(ptr %mem, i8 %num) { 102 %zext.num = zext i8 %num to i16 103 %sext.num = sext i8 %num to i16 104 %zext.sext.num = zext i16 %sext.num to i32 105 %sext.zext.num = sext i16 %zext.num to i32 106 %zext.zext.sext.num = zext i32 %zext.sext.num to i64 107 %zext.sext.zext.num = zext i32 %sext.zext.num to i64 108 %a = getelementptr inbounds i8, ptr %mem, i64 %zext.zext.sext.num 109 %b = getelementptr inbounds i8, ptr %mem, i64 %zext.sext.zext.num 110 load i8, ptr %a 111 load i8, ptr %b 112 ret void 113} 114 115; CHECK-LABEL: uncompressStream 116; CHECK: MustAlias: i8* %a, i8* %b 117; CHECK: NoAlias: i8* %a, i8* %c 118define void @uncompressStream(ptr %mem) { 119 %zext.255 = zext i8 255 to i32 120 %sext.255 = sext i8 255 to i32 121 %a = getelementptr inbounds i8, ptr %mem, i32 255 122 %b = getelementptr inbounds i8, ptr %mem, i32 %zext.255 123 %c = getelementptr inbounds i8, ptr %mem, i32 %sext.255 124 load i8, ptr %a 125 load i8, ptr %b 126 load i8, ptr %c 127 ret void 128} 129 130; CHECK-LABEL: constantOffsetHeuristic_i3_i32 131; CHECK: NoAlias: i32* %a, i32* %b 132; CHECK: NoAlias: i32* %a, i32* %c 133; CHECK: NoAlias: i32* %b, i32* %c 134define void @constantOffsetHeuristic_i3_i32(ptr %mem, i3 %val) { 135 %zext.plus.7 = add nsw i3 %val, 7 136 %zext.plus.4 = add nsw i3 %val, 4 137 %zext.val = zext i3 %val to i32 138 %zext.4 = zext i3 %zext.plus.4 to i32 139 %zext.7 = zext i3 %zext.plus.7 to i32 140 %a = getelementptr inbounds i32, ptr %mem, i32 %zext.4 141 %b = getelementptr inbounds i32, ptr %mem, i32 %zext.7 142 %c = getelementptr inbounds i32, ptr %mem, i32 %zext.val 143 load i32, ptr %a 144 load i32, ptr %b 145 load i32, ptr %c 146 ret void 147} 148 149; CHECK-LABEL: constantOffsetHeuristic_i8_i32 150; CHECK: NoAlias: i32* %a, i32* %b 151; CHECK: NoAlias: i32* %a, i32* %c 152; CHECK: NoAlias: i32* %b, i32* %c 153define void @constantOffsetHeuristic_i8_i32(ptr %mem, i8 %val) { 154 %zext.plus.7 = add nsw i8 %val, 7 155 %zext.plus.4 = add nsw i8 %val, 4 156 %zext.val = zext i8 %val to i32 157 %zext.4 = zext i8 %zext.plus.4 to i32 158 %zext.7 = zext i8 %zext.plus.7 to i32 159 %a = getelementptr inbounds i32, ptr %mem, i32 %zext.4 160 %b = getelementptr inbounds i32, ptr %mem, i32 %zext.7 161 %c = getelementptr inbounds i32, ptr %mem, i32 %zext.val 162 load i32, ptr %a 163 load i32, ptr %b 164 load i32, ptr %c 165 ret void 166} 167 168; CHECK-LABEL: constantOffsetHeuristic_i3_i8 169; CHECK: MayAlias: i32* %a.8, i32* %b.8 170; CHECK: NoAlias: i32* %a.8, i32* %c.8 171; CHECK: MayAlias: i32* %b.8, i32* %c.8 172define void @constantOffsetHeuristic_i3_i8(ptr %mem, i3 %val) { 173 %zext.plus.7 = add nsw i3 %val, 7 174 %zext.plus.4 = add nsw i3 %val, 4 175 %zext.val = zext i3 %val to i32 176 %zext.4 = zext i3 %zext.plus.4 to i32 177 %zext.7 = zext i3 %zext.plus.7 to i32 178 %a.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.4 179 %b.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.7 180 %c.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.val 181 load i32, ptr %a.8 182 load i32, ptr %b.8 183 load i32, ptr %c.8 184 ret void 185} 186 187; CHECK-LABEL: constantOffsetHeuristic_i8_i8 188; CHECK: MayAlias: i32* %a.8, i32* %b.8 189; CHECK: NoAlias: i32* %a.8, i32* %c.8 190; CHECK: NoAlias: i32* %b.8, i32* %c.8 191define void @constantOffsetHeuristic_i8_i8(ptr %mem, i8 %val) { 192 %zext.plus.7 = add nsw i8 %val, 7 193 %zext.plus.4 = add nsw i8 %val, 4 194 %zext.val = zext i8 %val to i32 195 %zext.4 = zext i8 %zext.plus.4 to i32 196 %zext.7 = zext i8 %zext.plus.7 to i32 197 %a.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.4 198 %b.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.7 199 %c.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.val 200 load i32, ptr %a.8 201 load i32, ptr %b.8 202 load i32, ptr %c.8 203 ret void 204} 205 206; CHECK-LABEL: different_large_bitwidths 207; MayAlias: ptr %p1, ptr %p2 208define void @different_large_bitwidths(ptr %a, i64 %i, i128 %j) { 209 %p1 = getelementptr i8, ptr %a, i64 %i 210 %p2 = getelementptr i8, ptr %a, i128 %j 211 load i8, ptr %p1 212 load i8, ptr %p2 213 ret void 214} 215