Skip to content

Commit

Permalink
[InstCombine] Fold align assume into load's !align metadata if possible
Browse files Browse the repository at this point in the history
  • Loading branch information
fhahn committed Jan 16, 2025
1 parent 8441043 commit 1e2b44f
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 17 deletions.
30 changes: 26 additions & 4 deletions llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3207,12 +3207,13 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
// TODO: apply range metadata for range check patterns?
}

// Separate storage assumptions apply to the underlying allocations, not any
// particular pointer within them. When evaluating the hints for AA purposes
// we getUnderlyingObject them; by precomputing the answers here we can
// avoid having to do so repeatedly there.
for (unsigned Idx = 0; Idx < II->getNumOperandBundles(); Idx++) {
OperandBundleUse OBU = II->getOperandBundleAt(Idx);

// Separate storage assumptions apply to the underlying allocations, not
// any particular pointer within them. When evaluating the hints for AA
// purposes we getUnderlyingObject them; by precomputing the answers here
// we can avoid having to do so repeatedly there.
if (OBU.getTagName() == "separate_storage") {
assert(OBU.Inputs.size() == 2);
auto MaybeSimplifyHint = [&](const Use &U) {
Expand All @@ -3226,6 +3227,27 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
MaybeSimplifyHint(OBU.Inputs[0]);
MaybeSimplifyHint(OBU.Inputs[1]);
}
// Try to fold alignment assumption into a load's !align metadata, if the
// assumption is valid in the load's context.
if (OBU.getTagName() == "align" && OBU.Inputs.size() == 2) {
RetainedKnowledge RK = getKnowledgeFromBundle(
*cast<AssumeInst>(II), II->bundle_op_info_begin()[Idx]);
if (!RK || RK.AttrKind != Attribute::Alignment ||
!isPowerOf2_64(RK.ArgValue))
continue;

auto *LI = dyn_cast<LoadInst>(OBU.Inputs[0]);
if (!LI ||
!isValidAssumeForContext(II, LI, &DT, /*AllowEphemerals=*/true))
continue;

LI->setMetadata(
LLVMContext::MD_align,
MDNode::get(II->getContext(), ValueAsMetadata::getConstant(
Builder.getInt64(RK.ArgValue))));
auto *New = CallBase::removeOperandBundle(II, OBU.getTagID());
return New;
}
}

// Convert nonnull assume like:
Expand Down
30 changes: 27 additions & 3 deletions llvm/test/Transforms/InstCombine/assume-align.ll
Original file line number Diff line number Diff line change
Expand Up @@ -123,18 +123,26 @@ define i8 @assume_align_non_pow2(ptr %p) {
ret i8 %v
}

; TODO: Can fold alignment assumption into !align metadata on load.
define ptr @fold_assume_align_pow2_of_loaded_pointer_into_align_metadata(ptr %p) {
; CHECK-LABEL: @fold_assume_align_pow2_of_loaded_pointer_into_align_metadata(
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 8) ]
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align [[META0:![0-9]+]]
; CHECK-NEXT: ret ptr [[P2]]
;
%p2 = load ptr, ptr %p
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 8) ]
ret ptr %p2
}

define ptr @fold_assume_align_i32_pow2_of_loaded_pointer_into_align_metadata(ptr %p) {
; CHECK-LABEL: @fold_assume_align_i32_pow2_of_loaded_pointer_into_align_metadata(
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align [[META0]]
; CHECK-NEXT: ret ptr [[P2]]
;
%p2 = load ptr, ptr %p
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i32 8) ]
ret ptr %p2
}

define ptr @dont_fold_assume_align_pow2_of_loaded_pointer_into_align_metadata_due_to_call(ptr %p) {
; CHECK-LABEL: @dont_fold_assume_align_pow2_of_loaded_pointer_into_align_metadata_due_to_call(
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
Expand Down Expand Up @@ -171,3 +179,19 @@ define ptr @dont_fold_assume_align_zero_of_loaded_pointer_into_align_metadata(pt
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 0) ]
ret ptr %p2
}

; !align must have a constant integer alignment.
define ptr @dont_fold_assume_align_not_constant_of_loaded_pointer_into_align_metadata(ptr %p, i64 %align) {
; CHECK-LABEL: @dont_fold_assume_align_not_constant_of_loaded_pointer_into_align_metadata(
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align [[META1:![0-9]+]]
; CHECK-NEXT: ret ptr [[P2]]
;
%p2 = load ptr, ptr %p
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 %align) ]
ret ptr %p2
}

;.
; CHECK: [[META0]] = !{i64 8}
; CHECK: [[META1]] = !{i64 1}
;.
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@ declare void @llvm.assume(i1 noundef)
define i32 @entry(ptr %0) {
; CHECK-LABEL: define i32 @entry(
; CHECK-SAME: ptr nocapture [[TMP0:%.*]]) local_unnamed_addr {
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP2]], i64 4) ]
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8, !align [[META0:![0-9]+]]
; CHECK-NEXT: [[DOT0_COPYLOAD_I_I_I:%.*]] = load i32, ptr [[TMP2]], align 4
; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 @swap(i32 [[DOT0_COPYLOAD_I_I_I]])
; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP0]], align 8
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP4]], i64 4
; CHECK-NEXT: store ptr [[TMP5]], ptr [[TMP0]], align 8
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP5]], i64 4) ]
; CHECK-NEXT: [[DOT0_COPYLOAD_I_I_I1:%.*]] = load i32, ptr [[TMP5]], align 4
; CHECK-NEXT: [[TMP6:%.*]] = tail call i32 @swap(i32 [[DOT0_COPYLOAD_I_I_I1]])
; CHECK-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP0]], align 8
Expand All @@ -32,8 +30,7 @@ define i32 @entry(ptr %0) {
define i32 @fn1(ptr %0) {
; CHECK-LABEL: define i32 @fn1(
; CHECK-SAME: ptr nocapture [[TMP0:%.*]]) local_unnamed_addr {
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP2]], i64 4) ]
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8, !align [[META0]]
; CHECK-NEXT: [[DOT0_COPYLOAD_I_I:%.*]] = load i32, ptr [[TMP2]], align 4
; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 @swap(i32 [[DOT0_COPYLOAD_I_I]])
; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP0]], align 8
Expand All @@ -48,8 +45,7 @@ define i32 @fn1(ptr %0) {
define i32 @fn2(ptr %0) {
; CHECK-LABEL: define i32 @fn2(
; CHECK-SAME: ptr nocapture [[TMP0:%.*]]) local_unnamed_addr {
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP2]], i64 4) ]
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8, !align [[META0]]
; CHECK-NEXT: [[DOT0_COPYLOAD_I:%.*]] = load i32, ptr [[TMP2]], align 4
; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 @swap(i32 [[DOT0_COPYLOAD_I]])
; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP0]], align 8
Expand All @@ -68,7 +64,6 @@ define i32 @fn2(ptr %0) {
define i32 @load_assume_aligned(ptr %0) {
; CHECK-LABEL: define i32 @load_assume_aligned(
; CHECK-SAME: ptr [[TMP0:%.*]]) local_unnamed_addr {
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP0]], i64 4) ]
; CHECK-NEXT: [[DOT0_COPYLOAD:%.*]] = load i32, ptr [[TMP0]], align 4
; CHECK-NEXT: [[TMP2:%.*]] = tail call i32 @swap(i32 [[DOT0_COPYLOAD]])
; CHECK-NEXT: ret i32 [[TMP2]]
Expand All @@ -80,3 +75,6 @@ define i32 @load_assume_aligned(ptr %0) {
}

declare i32 @swap(i32)
;.
; CHECK: [[META0]] = !{i64 4}
;.
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ define void @caller1(i1 %c, ptr align 1 %ptr) {
; ASSUMPTIONS-ON-NEXT: br i1 [[C:%.*]], label [[COMMON_RET:%.*]], label [[FALSE2:%.*]]
; ASSUMPTIONS-ON: common.ret:
; ASSUMPTIONS-ON-NEXT: [[DOTSINK:%.*]] = phi i64 [ 3, [[FALSE2]] ], [ 2, [[TMP0:%.*]] ]
; ASSUMPTIONS-ON-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR:%.*]], i64 8) ]
; ASSUMPTIONS-ON-NEXT: store volatile i64 0, ptr [[PTR]], align 8
; ASSUMPTIONS-ON-NEXT: store volatile i64 0, ptr [[PTR:%.*]], align 8
; ASSUMPTIONS-ON-NEXT: store volatile i64 -1, ptr [[PTR]], align 8
; ASSUMPTIONS-ON-NEXT: store volatile i64 -1, ptr [[PTR]], align 8
; ASSUMPTIONS-ON-NEXT: store volatile i64 -1, ptr [[PTR]], align 8
Expand Down

0 comments on commit 1e2b44f

Please sign in to comment.