1 target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128" 2 ; RUN: opt < %s -alignment-from-assumptions -S | FileCheck %s 3 4 define i32 @foo(i32* nocapture %a) nounwind uwtable readonly { 5 entry: 6 %ptrint = ptrtoint i32* %a to i64 7 %maskedptr = and i64 %ptrint, 31 8 %maskcond = icmp eq i64 %maskedptr, 0 9 tail call void @llvm.assume(i1 %maskcond) 10 %0 = load i32, i32* %a, align 4 11 ret i32 %0 12 13 ; CHECK-LABEL: @foo 14 ; CHECK: load i32, i32* {{[^,]+}}, align 32 15 ; CHECK: ret i32 16 } 17 18 define i32 @foo2(i32* nocapture %a) nounwind uwtable readonly { 19 entry: 20 %ptrint = ptrtoint i32* %a to i64 21 %offsetptr = add i64 %ptrint, 24 22 %maskedptr = and i64 %offsetptr, 31 23 %maskcond = icmp eq i64 %maskedptr, 0 24 tail call void @llvm.assume(i1 %maskcond) 25 %arrayidx = getelementptr inbounds i32, i32* %a, i64 2 26 %0 = load i32, i32* %arrayidx, align 4 27 ret i32 %0 28 29 ; CHECK-LABEL: @foo2 30 ; CHECK: load i32, i32* {{[^,]+}}, align 16 31 ; CHECK: ret i32 32 } 33 34 define i32 @foo2a(i32* nocapture %a) nounwind uwtable readonly { 35 entry: 36 %ptrint = ptrtoint i32* %a to i64 37 %offsetptr = add i64 %ptrint, 28 38 %maskedptr = and i64 %offsetptr, 31 39 %maskcond = icmp eq i64 %maskedptr, 0 40 tail call void @llvm.assume(i1 %maskcond) 41 %arrayidx = getelementptr inbounds i32, i32* %a, i64 -1 42 %0 = load i32, i32* %arrayidx, align 4 43 ret i32 %0 44 45 ; CHECK-LABEL: @foo2a 46 ; CHECK: load i32, i32* {{[^,]+}}, align 32 47 ; CHECK: ret i32 48 } 49 50 define i32 @goo(i32* nocapture %a) nounwind uwtable readonly { 51 entry: 52 %ptrint = ptrtoint i32* %a to i64 53 %maskedptr = and i64 %ptrint, 31 54 %maskcond = icmp eq i64 %maskedptr, 0 55 tail call void @llvm.assume(i1 %maskcond) 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 64 define i32 @hoo(i32* nocapture %a) nounwind uwtable readonly { 65 entry: 66 %ptrint = ptrtoint i32* %a to i64 67 %maskedptr = and i64 %ptrint, 31 68 %maskcond = icmp eq i64 %maskedptr, 0 69 tail call void @llvm.assume(i1 %maskcond) 70 br label %for.body 71 72 for.body: ; preds = %entry, %for.body 73 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 74 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 75 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 76 %0 = load i32, i32* %arrayidx, align 4 77 %add = add nsw i32 %0, %r.06 78 %indvars.iv.next = add i64 %indvars.iv, 8 79 %1 = trunc i64 %indvars.iv.next to i32 80 %cmp = icmp slt i32 %1, 2048 81 br i1 %cmp, label %for.body, label %for.end 82 83 for.end: ; preds = %for.body 84 %add.lcssa = phi i32 [ %add, %for.body ] 85 ret i32 %add.lcssa 86 87 ; CHECK-LABEL: @hoo 88 ; CHECK: load i32, i32* %arrayidx, align 32 89 ; CHECK: ret i32 %add.lcssa 90 } 91 92 define i32 @joo(i32* nocapture %a) nounwind uwtable readonly { 93 entry: 94 %ptrint = ptrtoint i32* %a to i64 95 %maskedptr = and i64 %ptrint, 31 96 %maskcond = icmp eq i64 %maskedptr, 0 97 tail call void @llvm.assume(i1 %maskcond) 98 br label %for.body 99 100 for.body: ; preds = %entry, %for.body 101 %indvars.iv = phi i64 [ 4, %entry ], [ %indvars.iv.next, %for.body ] 102 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 103 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 104 %0 = load i32, i32* %arrayidx, align 4 105 %add = add nsw i32 %0, %r.06 106 %indvars.iv.next = add i64 %indvars.iv, 8 107 %1 = trunc i64 %indvars.iv.next to i32 108 %cmp = icmp slt i32 %1, 2048 109 br i1 %cmp, label %for.body, label %for.end 110 111 for.end: ; preds = %for.body 112 %add.lcssa = phi i32 [ %add, %for.body ] 113 ret i32 %add.lcssa 114 115 ; CHECK-LABEL: @joo 116 ; CHECK: load i32, i32* %arrayidx, align 16 117 ; CHECK: ret i32 %add.lcssa 118 } 119 120 define i32 @koo(i32* nocapture %a) nounwind uwtable readonly { 121 entry: 122 %ptrint = ptrtoint i32* %a to i64 123 %maskedptr = and i64 %ptrint, 31 124 %maskcond = icmp eq i64 %maskedptr, 0 125 tail call void @llvm.assume(i1 %maskcond) 126 br label %for.body 127 128 for.body: ; preds = %entry, %for.body 129 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 130 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 131 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 132 %0 = load i32, i32* %arrayidx, align 4 133 %add = add nsw i32 %0, %r.06 134 %indvars.iv.next = add i64 %indvars.iv, 4 135 %1 = trunc i64 %indvars.iv.next to i32 136 %cmp = icmp slt i32 %1, 2048 137 br i1 %cmp, label %for.body, label %for.end 138 139 for.end: ; preds = %for.body 140 %add.lcssa = phi i32 [ %add, %for.body ] 141 ret i32 %add.lcssa 142 143 ; CHECK-LABEL: @koo 144 ; CHECK: load i32, i32* %arrayidx, align 16 145 ; CHECK: ret i32 %add.lcssa 146 } 147 148 define i32 @koo2(i32* nocapture %a) nounwind uwtable readonly { 149 entry: 150 %ptrint = ptrtoint i32* %a to i64 151 %maskedptr = and i64 %ptrint, 31 152 %maskcond = icmp eq i64 %maskedptr, 0 153 tail call void @llvm.assume(i1 %maskcond) 154 br label %for.body 155 156 for.body: ; preds = %entry, %for.body 157 %indvars.iv = phi i64 [ -4, %entry ], [ %indvars.iv.next, %for.body ] 158 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 159 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 160 %0 = load i32, i32* %arrayidx, align 4 161 %add = add nsw i32 %0, %r.06 162 %indvars.iv.next = add i64 %indvars.iv, 4 163 %1 = trunc i64 %indvars.iv.next to i32 164 %cmp = icmp slt i32 %1, 2048 165 br i1 %cmp, label %for.body, label %for.end 166 167 for.end: ; preds = %for.body 168 %add.lcssa = phi i32 [ %add, %for.body ] 169 ret i32 %add.lcssa 170 171 ; CHECK-LABEL: @koo2 172 ; CHECK: load i32, i32* %arrayidx, align 16 173 ; CHECK: ret i32 %add.lcssa 174 } 175 176 define i32 @moo(i32* nocapture %a) nounwind uwtable { 177 entry: 178 %ptrint = ptrtoint i32* %a to i64 179 %maskedptr = and i64 %ptrint, 31 180 %maskcond = icmp eq i64 %maskedptr, 0 181 tail call void @llvm.assume(i1 %maskcond) 182 %0 = bitcast i32* %a to i8* 183 tail call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 64, i32 4, i1 false) 184 ret i32 undef 185 186 ; CHECK-LABEL: @moo 187 ; CHECK: @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 64, i32 32, i1 false) 188 ; CHECK: ret i32 undef 189 } 190 191 define i32 @moo2(i32* nocapture %a, i32* nocapture %b) nounwind uwtable { 192 entry: 193 %ptrint = ptrtoint i32* %a to i64 194 %maskedptr = and i64 %ptrint, 31 195 %maskcond = icmp eq i64 %maskedptr, 0 196 tail call void @llvm.assume(i1 %maskcond) 197 %ptrint1 = ptrtoint i32* %b to i64 198 %maskedptr3 = and i64 %ptrint1, 127 199 %maskcond4 = icmp eq i64 %maskedptr3, 0 200 tail call void @llvm.assume(i1 %maskcond4) 201 %0 = bitcast i32* %a to i8* 202 %1 = bitcast i32* %b to i8* 203 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 64, i32 4, i1 false) 204 ret i32 undef 205 206 ; CHECK-LABEL: @moo2 207 ; CHECK: @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 64, i32 32, i1 false) 208 ; CHECK: ret i32 undef 209 } 210 211 declare void @llvm.assume(i1) nounwind 212 213 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind 214 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind 215 216