1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature 2target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64" 3; RUN: opt < %s -alignment-from-assumptions -S | FileCheck %s 4; RUN: opt < %s -passes=alignment-from-assumptions -S | FileCheck %s 5 6define i32 @foo(i32* nocapture %a) nounwind uwtable readonly { 7; CHECK-LABEL: define {{[^@]+}}@foo 8; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 9; CHECK-NEXT: entry: 10; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ] 11; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 32 12; CHECK-NEXT: ret i32 [[TMP0]] 13; 14entry: 15 call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)] 16 %0 = load i32, i32* %a, align 4 17 ret i32 %0 18 19} 20 21define i32 @foo2(i32* nocapture %a) nounwind uwtable readonly { 22; CHECK-LABEL: define {{[^@]+}}@foo2 23; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 24; CHECK-NEXT: entry: 25; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32, i64 24) ] 26; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 -2 27; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 16 28; CHECK-NEXT: ret i32 [[TMP0]] 29; 30entry: 31 call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32, i64 24)] 32 %arrayidx = getelementptr inbounds i32, i32* %a, i64 -2 33 %0 = load i32, i32* %arrayidx, align 4 34 ret i32 %0 35 36} 37 38define i32 @foo2a(i32* nocapture %a) nounwind uwtable readonly { 39; CHECK-LABEL: define {{[^@]+}}@foo2a 40; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 41; CHECK-NEXT: entry: 42; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32, i64 28) ] 43; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 1 44; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 32 45; CHECK-NEXT: ret i32 [[TMP0]] 46; 47entry: 48 call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32, i64 28)] 49 %arrayidx = getelementptr inbounds i32, i32* %a, i64 1 50 %0 = load i32, i32* %arrayidx, align 4 51 ret i32 %0 52 53} 54 55; TODO: this can be 8-bytes aligned 56define i32 @foo2b(i32* nocapture %a) nounwind uwtable readonly { 57; CHECK-LABEL: define {{[^@]+}}@foo2b 58; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 59; CHECK-NEXT: entry: 60; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32, i64 28) ] 61; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 -1 62; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 63; CHECK-NEXT: ret i32 [[TMP0]] 64; 65entry: 66 call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32, i64 28)] 67 %arrayidx = getelementptr inbounds i32, i32* %a, i64 -1 68 %0 = load i32, i32* %arrayidx, align 4 69 ret i32 %0 70 71} 72 73define i32 @goo(i32* nocapture %a) nounwind uwtable readonly { 74; CHECK-LABEL: define {{[^@]+}}@goo 75; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 76; CHECK-NEXT: entry: 77; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ] 78; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 32 79; CHECK-NEXT: ret i32 [[TMP0]] 80; 81entry: 82 call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)] 83 %0 = load i32, i32* %a, align 4 84 ret i32 %0 85 86} 87 88define i32 @hoo(i32* nocapture %a) nounwind uwtable readonly { 89; CHECK-LABEL: define {{[^@]+}}@hoo 90; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 91; CHECK-NEXT: entry: 92; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ] 93; CHECK-NEXT: br label [[FOR_BODY:%.*]] 94; CHECK: for.body: 95; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 96; CHECK-NEXT: [[R_06:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] 97; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]] 98; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 32 99; CHECK-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[R_06]] 100; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 8 101; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 102; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], 2048 103; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 104; CHECK: for.end: 105; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] 106; CHECK-NEXT: ret i32 [[ADD_LCSSA]] 107; 108entry: 109 call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)] 110 br label %for.body 111 112for.body: ; preds = %entry, %for.body 113 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 114 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 115 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 116 %0 = load i32, i32* %arrayidx, align 4 117 %add = add nsw i32 %0, %r.06 118 %indvars.iv.next = add i64 %indvars.iv, 8 119 %1 = trunc i64 %indvars.iv.next to i32 120 %cmp = icmp slt i32 %1, 2048 121 br i1 %cmp, label %for.body, label %for.end 122 123for.end: ; preds = %for.body 124 %add.lcssa = phi i32 [ %add, %for.body ] 125 ret i32 %add.lcssa 126 127} 128 129define i32 @joo(i32* nocapture %a) nounwind uwtable readonly { 130; CHECK-LABEL: define {{[^@]+}}@joo 131; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 132; CHECK-NEXT: entry: 133; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ] 134; CHECK-NEXT: br label [[FOR_BODY:%.*]] 135; CHECK: for.body: 136; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 4, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 137; CHECK-NEXT: [[R_06:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] 138; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]] 139; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 16 140; CHECK-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[R_06]] 141; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 8 142; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 143; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], 2048 144; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 145; CHECK: for.end: 146; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] 147; CHECK-NEXT: ret i32 [[ADD_LCSSA]] 148; 149entry: 150 call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)] 151 br label %for.body 152 153for.body: ; preds = %entry, %for.body 154 %indvars.iv = phi i64 [ 4, %entry ], [ %indvars.iv.next, %for.body ] 155 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 156 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 157 %0 = load i32, i32* %arrayidx, align 4 158 %add = add nsw i32 %0, %r.06 159 %indvars.iv.next = add i64 %indvars.iv, 8 160 %1 = trunc i64 %indvars.iv.next to i32 161 %cmp = icmp slt i32 %1, 2048 162 br i1 %cmp, label %for.body, label %for.end 163 164for.end: ; preds = %for.body 165 %add.lcssa = phi i32 [ %add, %for.body ] 166 ret i32 %add.lcssa 167 168} 169 170define i32 @koo(i32* nocapture %a) nounwind uwtable readonly { 171; CHECK-LABEL: define {{[^@]+}}@koo 172; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 173; CHECK-NEXT: entry: 174; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ] 175; CHECK-NEXT: br label [[FOR_BODY:%.*]] 176; CHECK: for.body: 177; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 178; CHECK-NEXT: [[R_06:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] 179; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]] 180; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 16 181; CHECK-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[R_06]] 182; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 4 183; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 184; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], 2048 185; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 186; CHECK: for.end: 187; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] 188; CHECK-NEXT: ret i32 [[ADD_LCSSA]] 189; 190entry: 191 call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)] 192 br label %for.body 193 194for.body: ; preds = %entry, %for.body 195 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 196 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 197 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 198 %0 = load i32, i32* %arrayidx, align 4 199 %add = add nsw i32 %0, %r.06 200 %indvars.iv.next = add i64 %indvars.iv, 4 201 %1 = trunc i64 %indvars.iv.next to i32 202 %cmp = icmp slt i32 %1, 2048 203 br i1 %cmp, label %for.body, label %for.end 204 205for.end: ; preds = %for.body 206 %add.lcssa = phi i32 [ %add, %for.body ] 207 ret i32 %add.lcssa 208 209} 210 211define i32 @koo2(i32* nocapture %a) nounwind uwtable readonly { 212; CHECK-LABEL: define {{[^@]+}}@koo2 213; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 214; CHECK-NEXT: entry: 215; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ] 216; CHECK-NEXT: br label [[FOR_BODY:%.*]] 217; CHECK: for.body: 218; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ -4, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 219; CHECK-NEXT: [[R_06:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] 220; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]] 221; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 16 222; CHECK-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[R_06]] 223; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 4 224; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 225; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], 2048 226; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 227; CHECK: for.end: 228; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] 229; CHECK-NEXT: ret i32 [[ADD_LCSSA]] 230; 231entry: 232 call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)] 233 br label %for.body 234 235for.body: ; preds = %entry, %for.body 236 %indvars.iv = phi i64 [ -4, %entry ], [ %indvars.iv.next, %for.body ] 237 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 238 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 239 %0 = load i32, i32* %arrayidx, align 4 240 %add = add nsw i32 %0, %r.06 241 %indvars.iv.next = add i64 %indvars.iv, 4 242 %1 = trunc i64 %indvars.iv.next to i32 243 %cmp = icmp slt i32 %1, 2048 244 br i1 %cmp, label %for.body, label %for.end 245 246for.end: ; preds = %for.body 247 %add.lcssa = phi i32 [ %add, %for.body ] 248 ret i32 %add.lcssa 249 250} 251 252define i32 @moo(i32* nocapture %a) nounwind uwtable { 253; CHECK-LABEL: define {{[^@]+}}@moo 254; CHECK-SAME: (i32* nocapture [[A:%.*]]) #1 255; CHECK-NEXT: entry: 256; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ] 257; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[A]] to i8* 258; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* align 32 [[TMP0]], i8 0, i64 64, i1 false) 259; CHECK-NEXT: ret i32 undef 260; 261entry: 262 call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)] 263 %0 = bitcast i32* %a to i8* 264 tail call void @llvm.memset.p0i8.i64(i8* align 4 %0, i8 0, i64 64, i1 false) 265 ret i32 undef 266 267} 268 269define i32 @moo2(i32* nocapture %a, i32* nocapture %b) nounwind uwtable { 270; CHECK-LABEL: define {{[^@]+}}@moo2 271; CHECK-SAME: (i32* nocapture [[A:%.*]], i32* nocapture [[B:%.*]]) #1 272; CHECK-NEXT: entry: 273; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32) ] 274; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[B]], i64 128) ] 275; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[A]] to i8* 276; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[B]] to i8* 277; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 32 [[TMP0]], i8* align 128 [[TMP1]], i64 64, i1 false) 278; CHECK-NEXT: ret i32 undef 279; 280entry: 281 call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32)] 282 call void @llvm.assume(i1 true) ["align"(i32* %b, i64 128)] 283 %0 = bitcast i32* %a to i8* 284 %1 = bitcast i32* %b to i8* 285 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 %1, i64 64, i1 false) 286 ret i32 undef 287 288} 289 290declare void @llvm.assume(i1) nounwind 291 292declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind 293declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind 294 295