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 40define i32 @goo(i32* nocapture %a) nounwind uwtable readonly { 41entry: 42 tail call void @llvm.assume(i1 true) ["align"(i32* %a, i32 32, i32 0)] 43 %0 = load i32, i32* %a, align 4 44 ret i32 %0 45 46; CHECK-LABEL: @goo 47; CHECK: load i32, i32* {{[^,]+}}, align 32 48; CHECK: ret i32 49} 50 51define i32 @hoo(i32* nocapture %a) nounwind uwtable readonly { 52entry: 53 tail call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32, i32 0)] 54 br label %for.body 55 56for.body: ; preds = %entry, %for.body 57 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 58 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 59 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 60 %0 = load i32, i32* %arrayidx, align 4 61 %add = add nsw i32 %0, %r.06 62 %indvars.iv.next = add i64 %indvars.iv, 8 63 %1 = trunc i64 %indvars.iv.next to i32 64 %cmp = icmp slt i32 %1, 2048 65 br i1 %cmp, label %for.body, label %for.end 66 67for.end: ; preds = %for.body 68 %add.lcssa = phi i32 [ %add, %for.body ] 69 ret i32 %add.lcssa 70 71; CHECK-LABEL: @hoo 72; CHECK: load i32, i32* %arrayidx, align 32 73; CHECK: ret i32 %add.lcssa 74} 75 76; test D66575 77; def hoo2(a, id, num): 78; for i0 in range(id*64, 4096, num*64): 79; for i1 in range(0, 4096, 32): 80; for i2 in range(0, 4096, 32): 81; load(a, i0+i1+i2+32) 82define void @hoo2(i32* nocapture %a, i64 %id, i64 %num) nounwind uwtable readonly { 83entry: 84 tail call void @llvm.assume(i1 true) ["align"(i32* %a, i8 32, i64 0)] 85 %id.mul = shl nsw i64 %id, 6 86 %num.mul = shl nsw i64 %num, 6 87 br label %for0.body 88 89for0.body: 90 %i0 = phi i64 [ %id.mul, %entry ], [ %i0.next, %for0.end ] 91 br label %for1.body 92 93for1.body: 94 %i1 = phi i64 [ 0, %for0.body ], [ %i1.next, %for1.end ] 95 br label %for2.body 96 97for2.body: 98 %i2 = phi i64 [ 0, %for1.body ], [ %i2.next, %for2.body ] 99 100 %t1 = add nuw nsw i64 %i0, %i1 101 %t2 = add nuw nsw i64 %t1, %i2 102 %t3 = add nuw nsw i64 %t2, 32 103 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %t3 104 %x = load i32, i32* %arrayidx, align 4 105 106 %i2.next = add nuw nsw i64 %i2, 32 107 %cmp2 = icmp ult i64 %i2.next, 4096 108 br i1 %cmp2, label %for2.body, label %for1.end 109 110for1.end: 111 %i1.next = add nuw nsw i64 %i1, 32 112 %cmp1 = icmp ult i64 %i1.next, 4096 113 br i1 %cmp1, label %for1.body, label %for0.end 114 115for0.end: 116 %i0.next = add nuw nsw i64 %i0, %num.mul 117 %cmp0 = icmp ult i64 %i0.next, 4096 118 br i1 %cmp0, label %for0.body, label %return 119 120return: 121 ret void 122 123; CHECK-LABEL: @hoo2 124; CHECK: load i32, i32* %arrayidx, align 32 125; CHECK: ret void 126} 127 128define i32 @joo(i32* nocapture %a) nounwind uwtable readonly { 129entry: 130 tail call void @llvm.assume(i1 true) ["align"(i32* %a, i8 32, i8 0)] 131 br label %for.body 132 133for.body: ; preds = %entry, %for.body 134 %indvars.iv = phi i64 [ 4, %entry ], [ %indvars.iv.next, %for.body ] 135 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 136 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 137 %0 = load i32, i32* %arrayidx, align 4 138 %add = add nsw i32 %0, %r.06 139 %indvars.iv.next = add i64 %indvars.iv, 8 140 %1 = trunc i64 %indvars.iv.next to i32 141 %cmp = icmp slt i32 %1, 2048 142 br i1 %cmp, label %for.body, label %for.end 143 144for.end: ; preds = %for.body 145 %add.lcssa = phi i32 [ %add, %for.body ] 146 ret i32 %add.lcssa 147 148; CHECK-LABEL: @joo 149; CHECK: load i32, i32* %arrayidx, align 16 150; CHECK: ret i32 %add.lcssa 151} 152 153define i32 @koo(i32* nocapture %a) nounwind uwtable readonly { 154entry: 155 br label %for.body 156 157for.body: ; preds = %entry, %for.body 158 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 159 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 160 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 161 tail call void @llvm.assume(i1 true) ["align"(i32* %a, i8 32, i8 0)] 162 %0 = load i32, i32* %arrayidx, align 4 163 %add = add nsw i32 %0, %r.06 164 %indvars.iv.next = add i64 %indvars.iv, 4 165 %1 = trunc i64 %indvars.iv.next to i32 166 %cmp = icmp slt i32 %1, 2048 167 br i1 %cmp, label %for.body, label %for.end 168 169for.end: ; preds = %for.body 170 %add.lcssa = phi i32 [ %add, %for.body ] 171 ret i32 %add.lcssa 172 173; CHECK-LABEL: @koo 174; CHECK: load i32, i32* %arrayidx, align 16 175; CHECK: ret i32 %add.lcssa 176} 177 178define i32 @koo2(i32* nocapture %a) nounwind uwtable readonly { 179entry: 180 tail call void @llvm.assume(i1 true) ["align"(i32* %a, i128 32, i128 0)] 181 br label %for.body 182 183for.body: ; preds = %entry, %for.body 184 %indvars.iv = phi i64 [ -4, %entry ], [ %indvars.iv.next, %for.body ] 185 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 186 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 187 %0 = load i32, i32* %arrayidx, align 4 188 %add = add nsw i32 %0, %r.06 189 %indvars.iv.next = add i64 %indvars.iv, 4 190 %1 = trunc i64 %indvars.iv.next to i32 191 %cmp = icmp slt i32 %1, 2048 192 br i1 %cmp, label %for.body, label %for.end 193 194for.end: ; preds = %for.body 195 %add.lcssa = phi i32 [ %add, %for.body ] 196 ret i32 %add.lcssa 197 198; CHECK-LABEL: @koo2 199; CHECK: load i32, i32* %arrayidx, align 16 200; CHECK: ret i32 %add.lcssa 201} 202 203define i32 @moo(i32* nocapture %a) nounwind uwtable { 204entry: 205 tail call void @llvm.assume(i1 true) ["align"(i32* %a, i16 32)] 206 %0 = bitcast i32* %a to i8* 207 tail call void @llvm.memset.p0i8.i64(i8* align 4 %0, i8 0, i64 64, i1 false) 208 ret i32 undef 209 210; CHECK-LABEL: @moo 211; CHECK: @llvm.memset.p0i8.i64(i8* align 32 %0, i8 0, i64 64, i1 false) 212; CHECK: ret i32 undef 213} 214 215define i32 @moo2(i32* nocapture %a, i32* nocapture %b) nounwind uwtable { 216entry: 217 tail call void @llvm.assume(i1 true) ["align"(i32* %b, i32 128)] 218 %0 = bitcast i32* %a to i8* 219 tail call void @llvm.assume(i1 true) ["align"(i8* %0, i16 32)] 220 %1 = bitcast i32* %b to i8* 221 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 %1, i64 64, i1 false) 222 ret i32 undef 223 224; CHECK-LABEL: @moo2 225; CHECK: @llvm.memcpy.p0i8.p0i8.i64(i8* align 32 %0, i8* align 128 %1, i64 64, i1 false) 226; CHECK: ret i32 undef 227} 228 229define i32 @moo3(i32* nocapture %a, i32* nocapture %b) nounwind uwtable { 230entry: 231 %0 = bitcast i32* %a to i8* 232 tail call void @llvm.assume(i1 true) ["align"(i8* %0, i16 32), "align"(i32* %b, i32 128)] 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: @moo3 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 242declare void @llvm.assume(i1) nounwind 243 244declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind 245declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind 246 247