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