| ; 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 i64 @base(ptr %ptr) { |
| ; CHECK-LABEL: define i64 @base( |
| ; CHECK-SAME: ptr [[PTR:%.*]]) { |
| ; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[PTR]], align 4 |
| ; CHECK-NEXT: [[V3:%.*]] = ptrtoint ptr [[PTR]] to i64 |
| ; CHECK-NEXT: [[V5:%.*]] = and i64 [[V3]], 2 |
| ; CHECK-NEXT: ret i64 0 |
| ; |
| %v1 = load i32, ptr %ptr, align 4 |
| %v3 = ptrtoint ptr %ptr to i64 |
| %v5 = and i64 %v3, 2 |
| ret i64 %v5 |
| } |
| |
| define i64 @best_alignment(ptr %ptr) { |
| ; CHECK-LABEL: define i64 @best_alignment( |
| ; CHECK-SAME: ptr [[PTR:%.*]]) { |
| ; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[PTR]], align 8 |
| ; CHECK-NEXT: [[V2:%.*]] = load i32, ptr [[PTR]], align 16 |
| ; CHECK-NEXT: [[V3:%.*]] = ptrtoint ptr [[PTR]] to i64 |
| ; CHECK-NEXT: [[V5:%.*]] = and i64 [[V3]], 15 |
| ; CHECK-NEXT: ret i64 0 |
| ; |
| %v1 = load i32, ptr %ptr, align 8 |
| %v2 = load i32, ptr %ptr, align 16 |
| %v3 = ptrtoint ptr %ptr to i64 |
| %v5 = and i64 %v3, 15 |
| ret i64 %v5 |
| } |
| |
| declare void @func() |
| |
| define i64 @negative_test(ptr %ptr) { |
| ; CHECK-LABEL: define i64 @negative_test( |
| ; CHECK-SAME: ptr [[PTR:%.*]]) { |
| ; CHECK-NEXT: [[V3:%.*]] = ptrtoint ptr [[PTR]] to i64 |
| ; CHECK-NEXT: [[V5:%.*]] = and i64 [[V3]], 2 |
| ; CHECK-NEXT: call void @func() |
| ; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[PTR]], align 4 |
| ; CHECK-NEXT: ret i64 [[V5]] |
| ; |
| %v3 = ptrtoint ptr %ptr to i64 |
| %v5 = and i64 %v3, 2 |
| call void @func() |
| %v1 = load i32, ptr %ptr, align 4 |
| ret i64 %v5 |
| } |
| |
| define i64 @ptrtoaddr(ptr %ptr) { |
| ; CHECK-LABEL: define i64 @ptrtoaddr( |
| ; CHECK-SAME: ptr [[PTR:%.*]]) { |
| ; CHECK-NEXT: [[V3:%.*]] = ptrtoaddr ptr [[PTR]] to i64 |
| ; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[PTR]], align 4 |
| ; CHECK-NEXT: [[V5:%.*]] = and i64 [[V3]], 2 |
| ; CHECK-NEXT: ret i64 0 |
| ; |
| %v3 = ptrtoaddr ptr %ptr to i64 |
| %v1 = load i32, ptr %ptr, align 4 |
| %v5 = and i64 %v3, 2 |
| ret i64 %v5 |
| } |
| |
| define i64 @redundant_mask(ptr %ptr) { |
| ; CHECK-LABEL: define i64 @redundant_mask( |
| ; CHECK-SAME: ptr [[PTR:%.*]]) { |
| ; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[PTR]], align 4 |
| ; CHECK-NEXT: [[INT:%.*]] = ptrtoint ptr [[PTR]] to i64 |
| ; CHECK-NEXT: [[MASK:%.*]] = and i64 [[INT]], -4 |
| ; CHECK-NEXT: ret i64 [[INT]] |
| ; |
| %load = load i32, ptr %ptr, align 4 |
| %int = ptrtoint ptr %ptr to i64 |
| %mask = and i64 %int, -4 |
| ret i64 %mask |
| } |
| |
| define i64 @redundant_mask2(ptr %ptr) { |
| ; CHECK-LABEL: define i64 @redundant_mask2( |
| ; CHECK-SAME: ptr [[PTR:%.*]]) { |
| ; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[PTR]], align 4 |
| ; CHECK-NEXT: [[INT:%.*]] = ptrtoint ptr [[PTR]] to i64 |
| ; CHECK-NEXT: [[MASK:%.*]] = and i64 [[INT]], -3 |
| ; CHECK-NEXT: ret i64 [[INT]] |
| ; |
| %load = load i32, ptr %ptr, align 4 |
| %int = ptrtoint ptr %ptr to i64 |
| %mask = and i64 %int, -3 |
| ret i64 %mask |
| } |
| |
| define i64 @not_redundant_mask(ptr %ptr) { |
| ; CHECK-LABEL: define i64 @not_redundant_mask( |
| ; CHECK-SAME: ptr [[PTR:%.*]]) { |
| ; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[PTR]], align 4 |
| ; CHECK-NEXT: [[INT:%.*]] = ptrtoint ptr [[PTR]] to i64 |
| ; CHECK-NEXT: [[MASK:%.*]] = and i64 [[INT]], -5 |
| ; CHECK-NEXT: ret i64 [[MASK]] |
| ; |
| %load = load i32, ptr %ptr, align 4 |
| %int = ptrtoint ptr %ptr to i64 |
| %mask = and i64 %int, -5 |
| ret i64 %mask |
| } |