Skip to content

Commit 4125a04

Browse files
committed
[InstCombine] Fold align assume into load's !align metadata if possible
#108958
1 parent 5073347 commit 4125a04

File tree

2 files changed

+54
-7
lines changed

2 files changed

+54
-7
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

+27-4
Original file line numberDiff line numberDiff line change
@@ -3207,12 +3207,13 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
32073207
// TODO: apply range metadata for range check patterns?
32083208
}
32093209

3210-
// Separate storage assumptions apply to the underlying allocations, not any
3211-
// particular pointer within them. When evaluating the hints for AA purposes
3212-
// we getUnderlyingObject them; by precomputing the answers here we can
3213-
// avoid having to do so repeatedly there.
32143210
for (unsigned Idx = 0; Idx < II->getNumOperandBundles(); Idx++) {
32153211
OperandBundleUse OBU = II->getOperandBundleAt(Idx);
3212+
3213+
// Separate storage assumptions apply to the underlying allocations, not
3214+
// any particular pointer within them. When evaluating the hints for AA
3215+
// purposes we getUnderlyingObject them; by precomputing the answers here
3216+
// we can avoid having to do so repeatedly there.
32163217
if (OBU.getTagName() == "separate_storage") {
32173218
assert(OBU.Inputs.size() == 2);
32183219
auto MaybeSimplifyHint = [&](const Use &U) {
@@ -3233,6 +3234,28 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
32333234
auto *New = CallBase::removeOperandBundle(II, OBU.getTagID());
32343235
return New;
32353236
}
3237+
3238+
// Try to fold alignment assumption into a load's !align metadata, if the
3239+
// assumption is valid in the load's context.
3240+
if (OBU.getTagName() == "align" && OBU.Inputs.size() == 2) {
3241+
RetainedKnowledge RK = getKnowledgeFromBundle(
3242+
*cast<AssumeInst>(II), II->bundle_op_info_begin()[Idx]);
3243+
if (!RK || RK.AttrKind != Attribute::Alignment ||
3244+
!isPowerOf2_64(RK.ArgValue))
3245+
continue;
3246+
3247+
auto *LI = dyn_cast<LoadInst>(OBU.Inputs[0]);
3248+
if (!LI ||
3249+
!isValidAssumeForContext(II, LI, &DT, /*AllowEphemerals=*/true))
3250+
continue;
3251+
3252+
LI->setMetadata(
3253+
LLVMContext::MD_align,
3254+
MDNode::get(II->getContext(), ValueAsMetadata::getConstant(
3255+
Builder.getInt64(RK.ArgValue))));
3256+
auto *New = CallBase::removeOperandBundle(II, OBU.getTagID());
3257+
return New;
3258+
}
32363259
}
32373260

32383261
// Convert nonnull assume like:

llvm/test/Transforms/InstCombine/assume-align.ll

+27-3
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,26 @@ define i8 @assume_align_non_pow2(ptr %p) {
123123
ret i8 %v
124124
}
125125

126-
; TODO: Can fold alignment assumption into !align metadata on load.
127126
define ptr @fold_assume_align_pow2_of_loaded_pointer_into_align_metadata(ptr %p) {
128127
; CHECK-LABEL: @fold_assume_align_pow2_of_loaded_pointer_into_align_metadata(
129-
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
130-
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 8) ]
128+
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align [[META0:![0-9]+]]
131129
; CHECK-NEXT: ret ptr [[P2]]
132130
;
133131
%p2 = load ptr, ptr %p
134132
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 8) ]
135133
ret ptr %p2
136134
}
137135

136+
define ptr @fold_assume_align_i32_pow2_of_loaded_pointer_into_align_metadata(ptr %p) {
137+
; CHECK-LABEL: @fold_assume_align_i32_pow2_of_loaded_pointer_into_align_metadata(
138+
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align [[META0]]
139+
; CHECK-NEXT: ret ptr [[P2]]
140+
;
141+
%p2 = load ptr, ptr %p
142+
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i32 8) ]
143+
ret ptr %p2
144+
}
145+
138146
define ptr @dont_fold_assume_align_pow2_of_loaded_pointer_into_align_metadata_due_to_call(ptr %p) {
139147
; CHECK-LABEL: @dont_fold_assume_align_pow2_of_loaded_pointer_into_align_metadata_due_to_call(
140148
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
@@ -171,3 +179,19 @@ define ptr @dont_fold_assume_align_zero_of_loaded_pointer_into_align_metadata(pt
171179
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 0) ]
172180
ret ptr %p2
173181
}
182+
183+
; !align must have a constant integer alignment.
184+
define ptr @dont_fold_assume_align_not_constant_of_loaded_pointer_into_align_metadata(ptr %p, i64 %align) {
185+
; CHECK-LABEL: @dont_fold_assume_align_not_constant_of_loaded_pointer_into_align_metadata(
186+
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align [[META1:![0-9]+]]
187+
; CHECK-NEXT: ret ptr [[P2]]
188+
;
189+
%p2 = load ptr, ptr %p
190+
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 %align) ]
191+
ret ptr %p2
192+
}
193+
194+
;.
195+
; CHECK: [[META0]] = !{i64 8}
196+
; CHECK: [[META1]] = !{i64 1}
197+
;.

0 commit comments

Comments
 (0)