; 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 }