1target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128" 2; RUN: opt < %s -passes=alignment-from-assumptions -S | FileCheck %s 3 4define i32 @foo(ptr nocapture %a) nounwind uwtable readonly { 5entry: 6 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i32 32)] 7 %0 = load i32, ptr %a, align 4 8 ret i32 %0 9 10; CHECK-LABEL: @foo 11; CHECK: load i32, ptr {{[^,]+}}, align 32 12; CHECK: ret i32 13} 14 15define i32 @foo2(ptr nocapture %a) nounwind uwtable readonly { 16entry: 17 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i32 32, i32 24)] 18 %arrayidx = getelementptr inbounds i32, ptr %a, i64 -2 19 %0 = load i32, ptr %arrayidx, align 4 20 ret i32 %0 21 22; CHECK-LABEL: @foo2 23; CHECK: load i32, ptr {{[^,]+}}, align 16 24; CHECK: ret i32 25} 26 27define i32 @foo2a(ptr nocapture %a) nounwind uwtable readonly { 28entry: 29 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i32 32, i32 28)] 30 %arrayidx = getelementptr inbounds i32, ptr %a, i64 1 31 %0 = load i32, ptr %arrayidx, align 4 32 ret i32 %0 33 34; CHECK-LABEL: @foo2a 35; CHECK: load i32, ptr {{[^,]+}}, align 32 36; CHECK: ret i32 37} 38 39; TODO: this can be 8-bytes aligned 40define i32 @foo2b(ptr nocapture %a) nounwind uwtable readonly { 41entry: 42 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i32 32, i32 28)] 43 %arrayidx = getelementptr inbounds i32, ptr %a, i64 -1 44 %0 = load i32, ptr %arrayidx, align 4 45 ret i32 %0 46 47; CHECK-LABEL: @foo2b 48; CHECK: load i32, ptr {{[^,]+}}, align 4 49; CHECK: ret i32 50} 51 52define i32 @goo(ptr nocapture %a) nounwind uwtable readonly { 53entry: 54 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i32 32, i32 0)] 55 %0 = load i32, ptr %a, align 4 56 ret i32 %0 57 58; CHECK-LABEL: @goo 59; CHECK: load i32, ptr {{[^,]+}}, align 32 60; CHECK: ret i32 61} 62 63define i32 @hoo(ptr nocapture %a) nounwind uwtable readonly { 64entry: 65 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i64 32, i32 0)] 66 br label %for.body 67 68for.body: ; preds = %entry, %for.body 69 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 70 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 71 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv 72 %0 = load i32, ptr %arrayidx, align 4 73 %add = add nsw i32 %0, %r.06 74 %indvars.iv.next = add i64 %indvars.iv, 8 75 %1 = trunc i64 %indvars.iv.next to i32 76 %cmp = icmp slt i32 %1, 2048 77 br i1 %cmp, label %for.body, label %for.end 78 79for.end: ; preds = %for.body 80 %add.lcssa = phi i32 [ %add, %for.body ] 81 ret i32 %add.lcssa 82 83; CHECK-LABEL: @hoo 84; CHECK: load i32, ptr %arrayidx, align 32 85; CHECK: ret i32 %add.lcssa 86} 87 88; test D66575 89; def hoo2(a, id, num): 90; for i0 in range(id*64, 4096, num*64): 91; for i1 in range(0, 4096, 32): 92; for i2 in range(0, 4096, 32): 93; load(a, i0+i1+i2+32) 94define void @hoo2(ptr nocapture %a, i64 %id, i64 %num) nounwind uwtable readonly { 95entry: 96 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i8 32, i64 0)] 97 %id.mul = shl nsw i64 %id, 6 98 %num.mul = shl nsw i64 %num, 6 99 br label %for0.body 100 101for0.body: 102 %i0 = phi i64 [ %id.mul, %entry ], [ %i0.next, %for0.end ] 103 br label %for1.body 104 105for1.body: 106 %i1 = phi i64 [ 0, %for0.body ], [ %i1.next, %for1.end ] 107 br label %for2.body 108 109for2.body: 110 %i2 = phi i64 [ 0, %for1.body ], [ %i2.next, %for2.body ] 111 112 %t1 = add nuw nsw i64 %i0, %i1 113 %t2 = add nuw nsw i64 %t1, %i2 114 %t3 = add nuw nsw i64 %t2, 32 115 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %t3 116 %x = load i32, ptr %arrayidx, align 4 117 118 %i2.next = add nuw nsw i64 %i2, 32 119 %cmp2 = icmp ult i64 %i2.next, 4096 120 br i1 %cmp2, label %for2.body, label %for1.end 121 122for1.end: 123 %i1.next = add nuw nsw i64 %i1, 32 124 %cmp1 = icmp ult i64 %i1.next, 4096 125 br i1 %cmp1, label %for1.body, label %for0.end 126 127for0.end: 128 %i0.next = add nuw nsw i64 %i0, %num.mul 129 %cmp0 = icmp ult i64 %i0.next, 4096 130 br i1 %cmp0, label %for0.body, label %return 131 132return: 133 ret void 134 135; CHECK-LABEL: @hoo2 136; CHECK: load i32, ptr %arrayidx, align 32 137; CHECK: ret void 138} 139 140define i32 @joo(ptr nocapture %a) nounwind uwtable readonly { 141entry: 142 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i8 32, i8 0)] 143 br label %for.body 144 145for.body: ; preds = %entry, %for.body 146 %indvars.iv = phi i64 [ 4, %entry ], [ %indvars.iv.next, %for.body ] 147 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 148 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv 149 %0 = load i32, ptr %arrayidx, align 4 150 %add = add nsw i32 %0, %r.06 151 %indvars.iv.next = add i64 %indvars.iv, 8 152 %1 = trunc i64 %indvars.iv.next to i32 153 %cmp = icmp slt i32 %1, 2048 154 br i1 %cmp, label %for.body, label %for.end 155 156for.end: ; preds = %for.body 157 %add.lcssa = phi i32 [ %add, %for.body ] 158 ret i32 %add.lcssa 159 160; CHECK-LABEL: @joo 161; CHECK: load i32, ptr %arrayidx, align 16 162; CHECK: ret i32 %add.lcssa 163} 164 165define i32 @koo(ptr nocapture %a) nounwind uwtable readonly { 166entry: 167 br label %for.body 168 169for.body: ; preds = %entry, %for.body 170 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 171 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 172 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv 173 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i8 32, i8 0)] 174 %0 = load i32, ptr %arrayidx, align 4 175 %add = add nsw i32 %0, %r.06 176 %indvars.iv.next = add i64 %indvars.iv, 4 177 %1 = trunc i64 %indvars.iv.next to i32 178 %cmp = icmp slt i32 %1, 2048 179 br i1 %cmp, label %for.body, label %for.end 180 181for.end: ; preds = %for.body 182 %add.lcssa = phi i32 [ %add, %for.body ] 183 ret i32 %add.lcssa 184 185; CHECK-LABEL: @koo 186; CHECK: load i32, ptr %arrayidx, align 16 187; CHECK: ret i32 %add.lcssa 188} 189 190define i32 @koo2(ptr nocapture %a) nounwind uwtable readonly { 191entry: 192 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i128 32, i128 0)] 193 br label %for.body 194 195for.body: ; preds = %entry, %for.body 196 %indvars.iv = phi i64 [ -4, %entry ], [ %indvars.iv.next, %for.body ] 197 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 198 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv 199 %0 = load i32, ptr %arrayidx, align 4 200 %add = add nsw i32 %0, %r.06 201 %indvars.iv.next = add i64 %indvars.iv, 4 202 %1 = trunc i64 %indvars.iv.next to i32 203 %cmp = icmp slt i32 %1, 2048 204 br i1 %cmp, label %for.body, label %for.end 205 206for.end: ; preds = %for.body 207 %add.lcssa = phi i32 [ %add, %for.body ] 208 ret i32 %add.lcssa 209 210; CHECK-LABEL: @koo2 211; CHECK: load i32, ptr %arrayidx, align 16 212; CHECK: ret i32 %add.lcssa 213} 214 215define i32 @moo(ptr nocapture %a) nounwind uwtable { 216entry: 217 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i16 32)] 218 tail call void @llvm.memset.p0.i64(ptr align 4 %a, i8 0, i64 64, i1 false) 219 ret i32 undef 220 221; CHECK-LABEL: @moo 222; CHECK: @llvm.memset.p0.i64(ptr align 32 %a, i8 0, i64 64, i1 false) 223; CHECK: ret i32 undef 224} 225 226define i32 @moo2(ptr nocapture %a, ptr nocapture %b) nounwind uwtable { 227entry: 228 tail call void @llvm.assume(i1 true) ["align"(ptr %b, i32 128)] 229 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i16 32)] 230 tail call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a, ptr align 4 %b, i64 64, i1 false) 231 ret i32 undef 232 233; CHECK-LABEL: @moo2 234; CHECK: @llvm.memcpy.p0.p0.i64(ptr align 32 %a, ptr align 128 %b, i64 64, i1 false) 235; CHECK: ret i32 undef 236} 237 238define i32 @moo3(ptr nocapture %a, ptr nocapture %b) nounwind uwtable { 239entry: 240 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i16 32), "align"(ptr %b, i32 128)] 241 tail call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a, ptr align 4 %b, i64 64, i1 false) 242 ret i32 undef 243 244; CHECK-LABEL: @moo3 245; CHECK: @llvm.memcpy.p0.p0.i64(ptr align 32 %a, ptr align 128 %b, i64 64, i1 false) 246; CHECK: ret i32 undef 247} 248 249 250; Variable alignments appear to be legal, don't crash 251define i32 @pr51680(ptr nocapture %a, i32 %align) nounwind uwtable readonly { 252entry: 253 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i32 %align)] 254 %0 = load i32, ptr %a, align 4 255 ret i32 %0 256 257; CHECK-LABEL: @pr51680 258; CHECK: load i32, ptr {{[^,]+}}, align 4 259; CHECK: ret i32 260} 261 262declare void @llvm.assume(i1) nounwind 263 264declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1) nounwind 265declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind 266 267