Skip to content

Commit 93a1470

Browse files
authored
[InstCombine] Remove redundant alignment assumptions. (#123348)
Use known bits to remove redundant alignment assumptions. Libc++ now adds alignment assumptions for std::vector::begin() and std::vector::end(), so I expect we will see quite a bit more assumptions in C++ [1]. Try to clean up some redundant ones to start with. [1] llvm/llvm-project#108961 PR: llvm/llvm-project#123348
1 parent a2a9601 commit 93a1470

File tree

3 files changed

+52
-24
lines changed

3 files changed

+52
-24
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3385,12 +3385,13 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
33853385
// TODO: apply range metadata for range check patterns?
33863386
}
33873387

3388-
// Separate storage assumptions apply to the underlying allocations, not any
3389-
// particular pointer within them. When evaluating the hints for AA purposes
3390-
// we getUnderlyingObject them; by precomputing the answers here we can
3391-
// avoid having to do so repeatedly there.
33923388
for (unsigned Idx = 0; Idx < II->getNumOperandBundles(); Idx++) {
33933389
OperandBundleUse OBU = II->getOperandBundleAt(Idx);
3390+
3391+
// Separate storage assumptions apply to the underlying allocations, not
3392+
// any particular pointer within them. When evaluating the hints for AA
3393+
// purposes we getUnderlyingObject them; by precomputing the answers here
3394+
// we can avoid having to do so repeatedly there.
33943395
if (OBU.getTagName() == "separate_storage") {
33953396
assert(OBU.Inputs.size() == 2);
33963397
auto MaybeSimplifyHint = [&](const Use &U) {
@@ -3404,6 +3405,32 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
34043405
MaybeSimplifyHint(OBU.Inputs[0]);
34053406
MaybeSimplifyHint(OBU.Inputs[1]);
34063407
}
3408+
3409+
// Try to remove redundant alignment assumptions.
3410+
if (OBU.getTagName() == "align" && OBU.Inputs.size() == 2) {
3411+
RetainedKnowledge RK = getKnowledgeFromOperandInAssume(
3412+
*cast<AssumeInst>(II), II->arg_size() + Idx);
3413+
if (!RK || RK.AttrKind != Attribute::Alignment ||
3414+
!isPowerOf2_64(RK.ArgValue) || !isa<ConstantInt>(RK.IRArgValue))
3415+
continue;
3416+
3417+
// Don't try to remove align assumptions for pointers derived from
3418+
// arguments. We might lose information if the function gets inline and
3419+
// the align argument attribute disappears.
3420+
Value *UO = getUnderlyingObject(RK.WasOn);
3421+
if (!UO || isa<Argument>(UO))
3422+
continue;
3423+
3424+
// Compute known bits for the pointer, passing nullptr as context to
3425+
// avoid computeKnownBits using the assumption we are about to remove
3426+
// for reasoning.
3427+
KnownBits Known = computeKnownBits(RK.WasOn, /*CtxI=*/nullptr);
3428+
unsigned TZ = std::min(Known.countMinTrailingZeros(),
3429+
Value::MaxAlignmentExponent);
3430+
if ((1ULL << TZ) < RK.ArgValue)
3431+
continue;
3432+
return CallBase::removeOperandBundle(II, OBU.getTagID());
3433+
}
34073434
}
34083435

34093436
// Convert nonnull assume like:

llvm/test/Analysis/BasicAA/featuretest.ll

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,14 @@ declare void @llvm.assume(i1)
1515
; operations on another array. Important for scientific codes.
1616
;
1717
define i32 @different_array_test(i64 %A, i64 %B) {
18-
; NO_ASSUME-LABEL: @different_array_test(
19-
; NO_ASSUME-NEXT: [[ARRAY11:%.*]] = alloca [100 x i32], align 4
20-
; NO_ASSUME-NEXT: [[ARRAY22:%.*]] = alloca [200 x i32], align 4
21-
; NO_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[ARRAY11]], i32 4) ]
22-
; NO_ASSUME-NEXT: call void @external(ptr nonnull [[ARRAY11]])
23-
; NO_ASSUME-NEXT: call void @external(ptr nonnull [[ARRAY22]])
24-
; NO_ASSUME-NEXT: [[POINTER2:%.*]] = getelementptr i32, ptr [[ARRAY22]], i64 [[B:%.*]]
25-
; NO_ASSUME-NEXT: store i32 7, ptr [[POINTER2]], align 4
26-
; NO_ASSUME-NEXT: ret i32 0
27-
;
28-
; USE_ASSUME-LABEL: @different_array_test(
29-
; USE_ASSUME-NEXT: [[ARRAY11:%.*]] = alloca [100 x i32], align 4
30-
; USE_ASSUME-NEXT: [[ARRAY22:%.*]] = alloca [200 x i32], align 4
31-
; USE_ASSUME-NEXT: call void @external(ptr nonnull [[ARRAY11]])
32-
; USE_ASSUME-NEXT: call void @external(ptr nonnull [[ARRAY22]])
33-
; USE_ASSUME-NEXT: [[POINTER2:%.*]] = getelementptr i32, ptr [[ARRAY22]], i64 [[B:%.*]]
34-
; USE_ASSUME-NEXT: store i32 7, ptr [[POINTER2]], align 4
35-
; USE_ASSUME-NEXT: ret i32 0
18+
; CHECK-LABEL: @different_array_test(
19+
; CHECK-NEXT: [[ARRAY11:%.*]] = alloca [100 x i32], align 4
20+
; CHECK-NEXT: [[ARRAY22:%.*]] = alloca [200 x i32], align 4
21+
; CHECK-NEXT: call void @external(ptr nonnull [[ARRAY11]])
22+
; CHECK-NEXT: call void @external(ptr nonnull [[ARRAY22]])
23+
; CHECK-NEXT: [[POINTER2:%.*]] = getelementptr i32, ptr [[ARRAY22]], i64 [[B:%.*]]
24+
; CHECK-NEXT: store i32 7, ptr [[POINTER2]], align 4
25+
; CHECK-NEXT: ret i32 0
3626
;
3727
%Array1 = alloca i32, i32 100
3828
%Array2 = alloca i32, i32 200

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,6 @@ define ptr @dont_fold_assume_align_zero_of_loaded_pointer_into_align_metadata(pt
175175
define ptr @redundant_assume_align_1(ptr %p) {
176176
; CHECK-LABEL: @redundant_assume_align_1(
177177
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
178-
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i32 1) ]
179178
; CHECK-NEXT: call void @foo(ptr [[P2]])
180179
; CHECK-NEXT: ret ptr [[P2]]
181180
;
@@ -189,7 +188,6 @@ define ptr @redundant_assume_align_1(ptr %p) {
189188
define ptr @redundant_assume_align_8_via_align_metadata(ptr %p) {
190189
; CHECK-LABEL: @redundant_assume_align_8_via_align_metadata(
191190
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align [[META0:![0-9]+]]
192-
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i32 8) ]
193191
; CHECK-NEXT: call void @foo(ptr [[P2]])
194192
; CHECK-NEXT: ret ptr [[P2]]
195193
;
@@ -250,6 +248,19 @@ define ptr @redundant_assume_align_8_via_asume(ptr %p) {
250248
}
251249

252250
declare void @foo(ptr)
251+
252+
; !align must have a constant integer alignment.
253+
define ptr @assume_load_pointer_result(ptr %p, i64 %align) {
254+
; CHECK-LABEL: @assume_load_pointer_result(
255+
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
256+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 [[ALIGN:%.*]]) ]
257+
; CHECK-NEXT: ret ptr [[P2]]
258+
;
259+
%p2 = load ptr, ptr %p
260+
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 %align) ]
261+
ret ptr %p2
262+
}
263+
253264
;.
254265
; CHECK: [[META0]] = !{i64 8}
255266
;.

0 commit comments

Comments
 (0)