| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: opt < %s -passes=infer-alignment -S | FileCheck %s | |
| define void @alignment_guard(ptr %p) { | |
| ; CHECK-LABEL: define void @alignment_guard( | |
| ; CHECK-SAME: ptr [[P:%.*]]) { | |
| ; CHECK-NEXT: [[ENTRY:.*:]] | |
| ; CHECK-NEXT: [[P_INT:%.*]] = ptrtoint ptr [[P]] to i64 | |
| ; CHECK-NEXT: [[MASKED:%.*]] = and i64 [[P_INT]], 7 | |
| ; CHECK-NEXT: [[ALIGNED:%.*]] = icmp eq i64 [[MASKED]], 0 | |
| ; CHECK-NEXT: br i1 [[ALIGNED]], label %[[ALIGNED_PATH:.*]], label %[[EXIT:.*]] | |
| ; CHECK: [[ALIGNED_PATH]]: | |
| ; CHECK-NEXT: [[LOAD:%.*]] = load i64, ptr [[P]], align 8 | |
| ; CHECK-NEXT: [[MISALIGNED:%.*]] = getelementptr i8, ptr [[P]], i64 4 | |
| ; CHECK-NEXT: [[MISALIGNED_LOAD:%.*]] = load i32, ptr [[MISALIGNED]], align 4 | |
| ; CHECK-NEXT: br label %[[EXIT]] | |
| ; CHECK: [[EXIT]]: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| %p.int = ptrtoint ptr %p to i64 | |
| %masked = and i64 %p.int, 7 | |
| %aligned = icmp eq i64 %masked, 0 | |
| br i1 %aligned, label %aligned.path, label %exit | |
| aligned.path: | |
| %load = load i64, ptr %p, align 1 | |
| %misaligned = getelementptr i8, ptr %p, i64 4 | |
| %misaligned.load = load i32, ptr %misaligned, align 1 | |
| br label %exit | |
| exit: | |
| ret void | |
| } | |
| define void @unaligned_successor(ptr %p) { | |
| ; CHECK-LABEL: define void @unaligned_successor( | |
| ; CHECK-SAME: ptr [[P:%.*]]) { | |
| ; CHECK-NEXT: [[ENTRY:.*:]] | |
| ; CHECK-NEXT: [[P_INT:%.*]] = ptrtoint ptr [[P]] to i64 | |
| ; CHECK-NEXT: [[MASKED:%.*]] = and i64 [[P_INT]], 7 | |
| ; CHECK-NEXT: [[ALIGNED:%.*]] = icmp eq i64 [[MASKED]], 0 | |
| ; CHECK-NEXT: br i1 [[ALIGNED]], label %[[EXIT:.*]], label %[[UNALIGNED:.*]] | |
| ; CHECK: [[UNALIGNED]]: | |
| ; CHECK-NEXT: [[LOAD:%.*]] = load i64, ptr [[P]], align 1 | |
| ; CHECK-NEXT: br label %[[EXIT]] | |
| ; CHECK: [[EXIT]]: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| %p.int = ptrtoint ptr %p to i64 | |
| %masked = and i64 %p.int, 7 | |
| %aligned = icmp eq i64 %masked, 0 | |
| br i1 %aligned, label %exit, label %unaligned | |
| unaligned: | |
| %load = load i64, ptr %p, align 1 | |
| br label %exit | |
| exit: | |
| ret void | |
| } | |
| define void @out_of_order_blocks(ptr %p) { | |
| ; CHECK-LABEL: define void @out_of_order_blocks( | |
| ; CHECK-SAME: ptr [[P:%.*]]) { | |
| ; CHECK-NEXT: [[ENTRY:.*:]] | |
| ; CHECK-NEXT: br label %[[GUARD:.*]] | |
| ; CHECK: [[ALIGNED_PATH:.*]]: | |
| ; CHECK-NEXT: [[LOAD:%.*]] = load i64, ptr [[P]], align 8 | |
| ; CHECK-NEXT: br label %[[EXIT:.*]] | |
| ; CHECK: [[GUARD]]: | |
| ; CHECK-NEXT: [[P_INT:%.*]] = ptrtoint ptr [[P]] to i64 | |
| ; CHECK-NEXT: [[MASKED:%.*]] = and i64 [[P_INT]], 7 | |
| ; CHECK-NEXT: [[ALIGNED:%.*]] = icmp eq i64 [[MASKED]], 0 | |
| ; CHECK-NEXT: br i1 [[ALIGNED]], label %[[ALIGNED_PATH]], label %[[EXIT]] | |
| ; CHECK: [[EXIT]]: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| br label %guard | |
| aligned.path: | |
| %load = load i64, ptr %p, align 1 | |
| br label %exit | |
| guard: | |
| %p.int = ptrtoint ptr %p to i64 | |
| %masked = and i64 %p.int, 7 | |
| %aligned = icmp eq i64 %masked, 0 | |
| br i1 %aligned, label %aligned.path, label %exit | |
| exit: | |
| ret void | |
| } |