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: [[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64 11; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 12; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 13; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) 14; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 32 15; CHECK-NEXT: ret i32 [[TMP0]] 16; 17entry: 18 %ptrint = ptrtoint i32* %a to i64 19 %maskedptr = and i64 %ptrint, 31 20 %maskcond = icmp eq i64 %maskedptr, 0 21 tail call void @llvm.assume(i1 %maskcond) 22 %0 = load i32, i32* %a, align 4 23 ret i32 %0 24 25} 26 27define i32 @foo2(i32* nocapture %a) nounwind uwtable readonly { 28; CHECK-LABEL: define {{[^@]+}}@foo2 29; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 30; CHECK-NEXT: entry: 31; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64 32; CHECK-NEXT: [[OFFSETPTR:%.*]] = add i64 [[PTRINT]], 24 33; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[OFFSETPTR]], 31 34; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 35; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) 36; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 2 37; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 16 38; CHECK-NEXT: ret i32 [[TMP0]] 39; 40entry: 41 %ptrint = ptrtoint i32* %a to i64 42 %offsetptr = add i64 %ptrint, 24 43 %maskedptr = and i64 %offsetptr, 31 44 %maskcond = icmp eq i64 %maskedptr, 0 45 tail call void @llvm.assume(i1 %maskcond) 46 %arrayidx = getelementptr inbounds i32, i32* %a, i64 2 47 %0 = load i32, i32* %arrayidx, align 4 48 ret i32 %0 49 50} 51 52define i32 @foo2a(i32* nocapture %a) nounwind uwtable readonly { 53; CHECK-LABEL: define {{[^@]+}}@foo2a 54; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 55; CHECK-NEXT: entry: 56; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64 57; CHECK-NEXT: [[OFFSETPTR:%.*]] = add i64 [[PTRINT]], 28 58; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[OFFSETPTR]], 31 59; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 60; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) 61; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 -1 62; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 32 63; CHECK-NEXT: ret i32 [[TMP0]] 64; 65entry: 66 %ptrint = ptrtoint i32* %a to i64 67 %offsetptr = add i64 %ptrint, 28 68 %maskedptr = and i64 %offsetptr, 31 69 %maskcond = icmp eq i64 %maskedptr, 0 70 tail call void @llvm.assume(i1 %maskcond) 71 %arrayidx = getelementptr inbounds i32, i32* %a, i64 -1 72 %0 = load i32, i32* %arrayidx, align 4 73 ret i32 %0 74 75} 76 77define i32 @goo(i32* nocapture %a) nounwind uwtable readonly { 78; CHECK-LABEL: define {{[^@]+}}@goo 79; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 80; CHECK-NEXT: entry: 81; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64 82; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 83; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 84; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) 85; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 32 86; CHECK-NEXT: ret i32 [[TMP0]] 87; 88entry: 89 %ptrint = ptrtoint i32* %a to i64 90 %maskedptr = and i64 %ptrint, 31 91 %maskcond = icmp eq i64 %maskedptr, 0 92 tail call void @llvm.assume(i1 %maskcond) 93 %0 = load i32, i32* %a, align 4 94 ret i32 %0 95 96} 97 98define i32 @hoo(i32* nocapture %a) nounwind uwtable readonly { 99; CHECK-LABEL: define {{[^@]+}}@hoo 100; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 101; CHECK-NEXT: entry: 102; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64 103; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 104; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 105; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) 106; CHECK-NEXT: br label [[FOR_BODY:%.*]] 107; CHECK: for.body: 108; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 109; CHECK-NEXT: [[R_06:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] 110; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]] 111; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 32 112; CHECK-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[R_06]] 113; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 8 114; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 115; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], 2048 116; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 117; CHECK: for.end: 118; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] 119; CHECK-NEXT: ret i32 [[ADD_LCSSA]] 120; 121entry: 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 128for.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, 8 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 139for.end: ; preds = %for.body 140 %add.lcssa = phi i32 [ %add, %for.body ] 141 ret i32 %add.lcssa 142 143} 144 145define i32 @joo(i32* nocapture %a) nounwind uwtable readonly { 146; CHECK-LABEL: define {{[^@]+}}@joo 147; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 148; CHECK-NEXT: entry: 149; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64 150; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 151; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 152; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) 153; CHECK-NEXT: br label [[FOR_BODY:%.*]] 154; CHECK: for.body: 155; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 4, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 156; CHECK-NEXT: [[R_06:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] 157; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]] 158; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 16 159; CHECK-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[R_06]] 160; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 8 161; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 162; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], 2048 163; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 164; CHECK: for.end: 165; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] 166; CHECK-NEXT: ret i32 [[ADD_LCSSA]] 167; 168entry: 169 %ptrint = ptrtoint i32* %a to i64 170 %maskedptr = and i64 %ptrint, 31 171 %maskcond = icmp eq i64 %maskedptr, 0 172 tail call void @llvm.assume(i1 %maskcond) 173 br label %for.body 174 175for.body: ; preds = %entry, %for.body 176 %indvars.iv = phi i64 [ 4, %entry ], [ %indvars.iv.next, %for.body ] 177 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 178 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 179 %0 = load i32, i32* %arrayidx, align 4 180 %add = add nsw i32 %0, %r.06 181 %indvars.iv.next = add i64 %indvars.iv, 8 182 %1 = trunc i64 %indvars.iv.next to i32 183 %cmp = icmp slt i32 %1, 2048 184 br i1 %cmp, label %for.body, label %for.end 185 186for.end: ; preds = %for.body 187 %add.lcssa = phi i32 [ %add, %for.body ] 188 ret i32 %add.lcssa 189 190} 191 192define i32 @koo(i32* nocapture %a) nounwind uwtable readonly { 193; CHECK-LABEL: define {{[^@]+}}@koo 194; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 195; CHECK-NEXT: entry: 196; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64 197; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 198; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 199; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) 200; CHECK-NEXT: br label [[FOR_BODY:%.*]] 201; CHECK: for.body: 202; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 203; CHECK-NEXT: [[R_06:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] 204; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]] 205; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 16 206; CHECK-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[R_06]] 207; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 4 208; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 209; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], 2048 210; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 211; CHECK: for.end: 212; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] 213; CHECK-NEXT: ret i32 [[ADD_LCSSA]] 214; 215entry: 216 %ptrint = ptrtoint i32* %a to i64 217 %maskedptr = and i64 %ptrint, 31 218 %maskcond = icmp eq i64 %maskedptr, 0 219 tail call void @llvm.assume(i1 %maskcond) 220 br label %for.body 221 222for.body: ; preds = %entry, %for.body 223 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 224 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 225 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 226 %0 = load i32, i32* %arrayidx, align 4 227 %add = add nsw i32 %0, %r.06 228 %indvars.iv.next = add i64 %indvars.iv, 4 229 %1 = trunc i64 %indvars.iv.next to i32 230 %cmp = icmp slt i32 %1, 2048 231 br i1 %cmp, label %for.body, label %for.end 232 233for.end: ; preds = %for.body 234 %add.lcssa = phi i32 [ %add, %for.body ] 235 ret i32 %add.lcssa 236 237} 238 239define i32 @koo2(i32* nocapture %a) nounwind uwtable readonly { 240; CHECK-LABEL: define {{[^@]+}}@koo2 241; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0 242; CHECK-NEXT: entry: 243; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64 244; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 245; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 246; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) 247; CHECK-NEXT: br label [[FOR_BODY:%.*]] 248; CHECK: for.body: 249; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ -4, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 250; CHECK-NEXT: [[R_06:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] 251; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]] 252; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 16 253; CHECK-NEXT: [[ADD]] = add nsw i32 [[TMP0]], [[R_06]] 254; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 4 255; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 256; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP1]], 2048 257; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 258; CHECK: for.end: 259; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] 260; CHECK-NEXT: ret i32 [[ADD_LCSSA]] 261; 262entry: 263 %ptrint = ptrtoint i32* %a to i64 264 %maskedptr = and i64 %ptrint, 31 265 %maskcond = icmp eq i64 %maskedptr, 0 266 tail call void @llvm.assume(i1 %maskcond) 267 br label %for.body 268 269for.body: ; preds = %entry, %for.body 270 %indvars.iv = phi i64 [ -4, %entry ], [ %indvars.iv.next, %for.body ] 271 %r.06 = phi i32 [ 0, %entry ], [ %add, %for.body ] 272 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 273 %0 = load i32, i32* %arrayidx, align 4 274 %add = add nsw i32 %0, %r.06 275 %indvars.iv.next = add i64 %indvars.iv, 4 276 %1 = trunc i64 %indvars.iv.next to i32 277 %cmp = icmp slt i32 %1, 2048 278 br i1 %cmp, label %for.body, label %for.end 279 280for.end: ; preds = %for.body 281 %add.lcssa = phi i32 [ %add, %for.body ] 282 ret i32 %add.lcssa 283 284} 285 286define i32 @moo(i32* nocapture %a) nounwind uwtable { 287; CHECK-LABEL: define {{[^@]+}}@moo 288; CHECK-SAME: (i32* nocapture [[A:%.*]]) #1 289; CHECK-NEXT: entry: 290; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64 291; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 292; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 293; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) 294; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[A]] to i8* 295; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* align 32 [[TMP0]], i8 0, i64 64, i1 false) 296; CHECK-NEXT: ret i32 undef 297; 298entry: 299 %ptrint = ptrtoint i32* %a to i64 300 %maskedptr = and i64 %ptrint, 31 301 %maskcond = icmp eq i64 %maskedptr, 0 302 tail call void @llvm.assume(i1 %maskcond) 303 %0 = bitcast i32* %a to i8* 304 tail call void @llvm.memset.p0i8.i64(i8* align 4 %0, i8 0, i64 64, i1 false) 305 ret i32 undef 306 307} 308 309define i32 @moo2(i32* nocapture %a, i32* nocapture %b) nounwind uwtable { 310; CHECK-LABEL: define {{[^@]+}}@moo2 311; CHECK-SAME: (i32* nocapture [[A:%.*]], i32* nocapture [[B:%.*]]) #1 312; CHECK-NEXT: entry: 313; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[A]] to i64 314; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 315; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 316; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]]) 317; CHECK-NEXT: [[PTRINT1:%.*]] = ptrtoint i32* [[B]] to i64 318; CHECK-NEXT: [[MASKEDPTR3:%.*]] = and i64 [[PTRINT1]], 127 319; CHECK-NEXT: [[MASKCOND4:%.*]] = icmp eq i64 [[MASKEDPTR3]], 0 320; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND4]]) 321; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[A]] to i8* 322; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[B]] to i8* 323; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 32 [[TMP0]], i8* align 128 [[TMP1]], i64 64, i1 false) 324; CHECK-NEXT: ret i32 undef 325; 326entry: 327 %ptrint = ptrtoint i32* %a to i64 328 %maskedptr = and i64 %ptrint, 31 329 %maskcond = icmp eq i64 %maskedptr, 0 330 tail call void @llvm.assume(i1 %maskcond) 331 %ptrint1 = ptrtoint i32* %b to i64 332 %maskedptr3 = and i64 %ptrint1, 127 333 %maskcond4 = icmp eq i64 %maskedptr3, 0 334 tail call void @llvm.assume(i1 %maskcond4) 335 %0 = bitcast i32* %a to i8* 336 %1 = bitcast i32* %b to i8* 337 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 %1, i64 64, i1 false) 338 ret i32 undef 339 340} 341 342declare void @llvm.assume(i1) nounwind 343 344declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind 345declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind 346 347