249 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt < %s -passes=infer-alignment -S | FileCheck %s3 4; ------------------------------------------------------------------------------5; Simple test6; ------------------------------------------------------------------------------7 8define void @simple_forwardpropagate(ptr %a) {9; CHECK-LABEL: define void @simple_forwardpropagate10; CHECK-SAME: (ptr [[A:%.*]]) {11; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint ptr [[A]] to i6412; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 3113; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 014; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])15; CHECK-NEXT: [[LOAD_A:%.*]] = load i32, ptr [[A]], align 3216; CHECK-NEXT: store i32 345, ptr [[A]], align 3217; CHECK-NEXT: ret void18;19 %ptrint = ptrtoint ptr %a to i6420 %maskedptr = and i64 %ptrint, 3121 %maskcond = icmp eq i64 %maskedptr, 022 tail call void @llvm.assume(i1 %maskcond)23 24 %load.a = load i32, ptr %a, align 425 store i32 345, ptr %a, align 426 27 ret void28}29 30define void @simple_backpropagate(ptr %a) {31; CHECK-LABEL: define void @simple_backpropagate32; CHECK-SAME: (ptr [[A:%.*]]) {33; CHECK-NEXT: [[LOAD_A:%.*]] = load i32, ptr [[A]], align 3234; CHECK-NEXT: store i32 345, ptr [[A]], align 3235; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint ptr [[A]] to i6436; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 3137; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 038; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])39; CHECK-NEXT: ret void40;41 %load.a = load i32, ptr %a, align 442 store i32 345, ptr %a, align 443 44 %ptrint = ptrtoint ptr %a to i6445 %maskedptr = and i64 %ptrint, 3146 %maskcond = icmp eq i64 %maskedptr, 047 tail call void @llvm.assume(i1 %maskcond)48 49 ret void50}51 52define void @simple_forwardpropagate_bundle(ptr %a) {53; CHECK-LABEL: define void @simple_forwardpropagate_bundle54; CHECK-SAME: (ptr [[A:%.*]]) {55; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i32 32) ]56; CHECK-NEXT: [[LOAD_A:%.*]] = load i32, ptr [[A]], align 3257; CHECK-NEXT: store i32 345, ptr [[A]], align 3258; CHECK-NEXT: ret void59;60 call void @llvm.assume(i1 true) ["align"(ptr %a, i32 32)]61 %load.a = load i32, ptr %a, align 462 store i32 345, ptr %a, align 463 ret void64}65 66define void @simple_backpropagate_bundle(ptr %a) {67; CHECK-LABEL: define void @simple_backpropagate_bundle68; CHECK-SAME: (ptr [[A:%.*]]) {69; CHECK-NEXT: [[LOAD_A:%.*]] = load i32, ptr [[A]], align 3270; CHECK-NEXT: store i32 345, ptr [[A]], align 3271; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i32 32) ]72; CHECK-NEXT: ret void73;74 %load.a = load i32, ptr %a, align 475 store i32 345, ptr %a, align 476 call void @llvm.assume(i1 true) ["align"(ptr %a, i32 32)]77 ret void78}79 80; ------------------------------------------------------------------------------81; Complex test82; ------------------------------------------------------------------------------83 84define void @loop_forwardpropagate(ptr %a, ptr %b) {85; CHECK-LABEL: define void @loop_forwardpropagate86; CHECK-SAME: (ptr [[A:%.*]], ptr [[B:%.*]]) {87; CHECK-NEXT: entry:88; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint ptr [[A]] to i6489; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 6390; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 091; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])92; CHECK-NEXT: [[PTRINT2:%.*]] = ptrtoint ptr [[B]] to i6493; CHECK-NEXT: [[MASKEDPTR2:%.*]] = and i64 [[PTRINT2]], 6394; CHECK-NEXT: [[MASKEDCOND2:%.*]] = icmp eq i64 [[MASKEDPTR2]], 095; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKEDCOND2]])96; CHECK-NEXT: br label [[FOR_BODY:%.*]]97; CHECK: for.body:98; CHECK-NEXT: [[I:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[FOR_BODY]] ]99; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[I]]100; CHECK-NEXT: [[LOAD_B:%.*]] = load i32, ptr [[GEP_B]], align 64101; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LOAD_B]], 1102; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[I]]103; CHECK-NEXT: store i32 [[ADD]], ptr [[GEP_A]], align 64104; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 16105; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_NEXT]], 1648106; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]107; CHECK: for.end:108; CHECK-NEXT: ret void109;110entry:111 %ptrint = ptrtoint ptr %a to i64112 %maskedptr = and i64 %ptrint, 63113 %maskcond = icmp eq i64 %maskedptr, 0114 tail call void @llvm.assume(i1 %maskcond)115 116 %ptrint2 = ptrtoint ptr %b to i64117 %maskedptr2 = and i64 %ptrint2, 63118 %maskedcond2 = icmp eq i64 %maskedptr2, 0119 tail call void @llvm.assume(i1 %maskedcond2)120 121 br label %for.body122 123for.body:124 %i = phi i64 [ 0, %entry ], [ %i.next, %for.body ]125 126 %gep.b = getelementptr inbounds i32, ptr %b, i64 %i127 %load.b = load i32, ptr %gep.b, align 4128 %add = add nsw i32 %load.b, 1129 130 %gep.a = getelementptr inbounds i32, ptr %a, i64 %i131 store i32 %add, ptr %gep.a, align 4132 133 %i.next = add nuw nsw i64 %i, 16134 %cmp = icmp slt i64 %i.next, 1648135 136 br i1 %cmp, label %for.body, label %for.end137 138for.end:139 ret void140}141 142define void @loop_forwardpropagate_bundle(ptr %a, ptr %b) {143; CHECK-LABEL: define void @loop_forwardpropagate_bundle144; CHECK-SAME: (ptr [[A:%.*]], ptr [[B:%.*]]) {145; CHECK-NEXT: entry:146; CHECK-NEXT: tail call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i32 64) ]147; CHECK-NEXT: tail call void @llvm.assume(i1 true) [ "align"(ptr [[B]], i32 64) ]148; CHECK-NEXT: br label [[FOR_BODY:%.*]]149; CHECK: for.body:150; CHECK-NEXT: [[I:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[FOR_BODY]] ]151; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[I]]152; CHECK-NEXT: [[LOAD_B:%.*]] = load i32, ptr [[GEP_B]], align 64153; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LOAD_B]], 1154; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[I]]155; CHECK-NEXT: store i32 [[ADD]], ptr [[GEP_A]], align 64156; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 16157; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_NEXT]], 1648158; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]159; CHECK: for.end:160; CHECK-NEXT: ret void161;162entry:163 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i32 64)]164 tail call void @llvm.assume(i1 true) ["align"(ptr %b, i32 64)]165 br label %for.body166 167for.body:168 %i = phi i64 [ 0, %entry ], [ %i.next, %for.body ]169 170 %gep.b = getelementptr inbounds i32, ptr %b, i64 %i171 %load.b = load i32, ptr %gep.b, align 4172 %add = add nsw i32 %load.b, 1173 174 %gep.a = getelementptr inbounds i32, ptr %a, i64 %i175 store i32 %add, ptr %gep.a, align 4176 177 %i.next = add nuw nsw i64 %i, 16178 %cmp = icmp slt i64 %i.next, 1648179 180 br i1 %cmp, label %for.body, label %for.end181 182for.end:183 ret void184}185 186; Check that assume is propagated backwards through all187; operations that are `isGuaranteedToTransferExecutionToSuccessor`188; (it should reach the load and mark it as `align 32`).189define void @complex_backpropagate(ptr %a, ptr %b, ptr %c) {190; CHECK-LABEL: define void @complex_backpropagate191; CHECK-SAME: (ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]]) {192; CHECK-NEXT: [[ALLOCA:%.*]] = alloca i64, align 8193; CHECK-NEXT: [[LOAD_A:%.*]] = load i32, ptr [[A]], align 32194; CHECK-NEXT: [[LOAD_B:%.*]] = load i32, ptr [[B]], align 4195; CHECK-NEXT: store i32 [[LOAD_B]], ptr [[A]], align 32196; CHECK-NEXT: [[OBJ_SIZE:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[C]], i1 false, i1 false, i1 false)197; CHECK-NEXT: store i64 [[OBJ_SIZE]], ptr [[ALLOCA]], align 8198; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint ptr [[A]] to i64199; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31200; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0201; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])202; CHECK-NEXT: ret void203;204 %alloca = alloca i64205 %load.a = load i32, ptr %a, align 4206 207 %load.b = load i32, ptr %b208 store i32 %load.b, ptr %a209 210 %obj.size = call i64 @llvm.objectsize.i64.p0(ptr %c, i1 false)211 store i64 %obj.size, ptr %alloca212 213 %ptrint = ptrtoint ptr %a to i64214 %maskedptr = and i64 %ptrint, 31215 %maskcond = icmp eq i64 %maskedptr, 0216 tail call void @llvm.assume(i1 %maskcond)217 218 ret void219}220 221define void @complex_backpropagate_bundle(ptr %a, ptr %b, ptr %c) {222; CHECK-LABEL: define void @complex_backpropagate_bundle223; CHECK-SAME: (ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]]) {224; CHECK-NEXT: [[ALLOCA:%.*]] = alloca i64, align 8225; CHECK-NEXT: [[LOAD_A:%.*]] = load i32, ptr [[A]], align 32226; CHECK-NEXT: [[LOAD_B:%.*]] = load i32, ptr [[B]], align 4227; CHECK-NEXT: store i32 [[LOAD_B]], ptr [[A]], align 32228; CHECK-NEXT: [[OBJ_SIZE:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[C]], i1 false, i1 false, i1 false)229; CHECK-NEXT: store i64 [[OBJ_SIZE]], ptr [[ALLOCA]], align 8230; CHECK-NEXT: tail call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i32 32) ]231; CHECK-NEXT: ret void232;233 %alloca = alloca i64234 %load.a = load i32, ptr %a, align 4235 236 %load.b = load i32, ptr %b237 store i32 %load.b, ptr %a238 239 %obj.size = call i64 @llvm.objectsize.i64.p0(ptr %c, i1 false)240 store i64 %obj.size, ptr %alloca241 242 tail call void @llvm.assume(i1 true) ["align"(ptr %a, i32 32)]243 244 ret void245}246 247declare i64 @llvm.objectsize.i64.p0(ptr, i1)248declare void @llvm.assume(i1)249