Skip to content

Commit bfd0c02

Browse files
committed
[InstCombine] Remove redundant alignment assumptions.
1 parent 6dc356d commit bfd0c02

File tree

3 files changed

+92
-11
lines changed

3 files changed

+92
-11
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3226,12 +3226,13 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
32263226
// TODO: apply range metadata for range check patterns?
32273227
}
32283228

3229-
// Separate storage assumptions apply to the underlying allocations, not any
3230-
// particular pointer within them. When evaluating the hints for AA purposes
3231-
// we getUnderlyingObject them; by precomputing the answers here we can
3232-
// avoid having to do so repeatedly there.
32333229
for (unsigned Idx = 0; Idx < II->getNumOperandBundles(); Idx++) {
32343230
OperandBundleUse OBU = II->getOperandBundleAt(Idx);
3231+
3232+
// Separate storage assumptions apply to the underlying allocations, not
3233+
// any particular pointer within them. When evaluating the hints for AA
3234+
// purposes we getUnderlyingObject them; by precomputing the answers here
3235+
// we can avoid having to do so repeatedly there.
32353236
if (OBU.getTagName() == "separate_storage") {
32363237
assert(OBU.Inputs.size() == 2);
32373238
auto MaybeSimplifyHint = [&](const Use &U) {
@@ -3245,6 +3246,36 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
32453246
MaybeSimplifyHint(OBU.Inputs[0]);
32463247
MaybeSimplifyHint(OBU.Inputs[1]);
32473248
}
3249+
3250+
// Try to fold alignment assumption into a load's !align metadata, if the
3251+
// assumption is valid in the load's context and remove redundant ones.
3252+
if (OBU.getTagName() == "align" && OBU.Inputs.size() == 2) {
3253+
RetainedKnowledge RK = getKnowledgeFromBundle(
3254+
*cast<AssumeInst>(II), II->bundle_op_info_begin()[Idx]);
3255+
if (!RK || RK.AttrKind != Attribute::Alignment ||
3256+
!isPowerOf2_64(RK.ArgValue))
3257+
continue;
3258+
auto *C = dyn_cast<Constant>(RK.WasOn);
3259+
if (C && C->isNullValue()) {
3260+
} else {
3261+
Value *UO = getUnderlyingObject(RK.WasOn);
3262+
if (!UO || isa<Argument>(UO))
3263+
continue;
3264+
3265+
// Try to get the instruction before the assumption to use as
3266+
// context.
3267+
Instruction *CtxI = nullptr;
3268+
if (CtxI && II->getParent()->begin() != II->getIterator())
3269+
CtxI = II->getPrevNode();
3270+
3271+
auto Known = computeKnownBits(RK.WasOn, 1, CtxI);
3272+
unsigned KnownAlign = 1 << Known.countMinTrailingZeros();
3273+
if (KnownAlign < RK.ArgValue)
3274+
continue;
3275+
}
3276+
auto *New = CallBase::removeOperandBundle(II, OBU.getTagID());
3277+
return New;
3278+
}
32483279
}
32493280

32503281
// Convert nonnull assume like:

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

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals smart
2-
; RUN: opt -S -passes=instcombine,simplifycfg < %s 2>&1 | FileCheck %s
2+
; RUN: opt -S -passes='instcombine<no-verify-fixpoint>,simplifycfg' < %s 2>&1 | FileCheck %s
33

44
declare void @llvm.assume(i1 noundef)
55

@@ -135,6 +135,17 @@ define ptr @fold_assume_align_pow2_of_loaded_pointer_into_align_metadata(ptr %p)
135135
ret ptr %p2
136136
}
137137

138+
define ptr @fold_assume_align_i32_pow2_of_loaded_pointer_into_align_metadata(ptr %p) {
139+
; CHECK-LABEL: @fold_assume_align_i32_pow2_of_loaded_pointer_into_align_metadata(
140+
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
141+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i32 8) ]
142+
; CHECK-NEXT: ret ptr [[P2]]
143+
;
144+
%p2 = load ptr, ptr %p
145+
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i32 8) ]
146+
ret ptr %p2
147+
}
148+
138149
define ptr @dont_fold_assume_align_pow2_of_loaded_pointer_into_align_metadata_due_to_call(ptr %p) {
139150
; CHECK-LABEL: @dont_fold_assume_align_pow2_of_loaded_pointer_into_align_metadata_due_to_call(
140151
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
@@ -175,7 +186,6 @@ define ptr @dont_fold_assume_align_zero_of_loaded_pointer_into_align_metadata(pt
175186
define ptr @redundant_assume_align_1(ptr %p) {
176187
; CHECK-LABEL: @redundant_assume_align_1(
177188
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
178-
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i32 1) ]
179189
; CHECK-NEXT: call void @foo(ptr [[P2]])
180190
; CHECK-NEXT: ret ptr [[P2]]
181191
;
@@ -189,7 +199,6 @@ define ptr @redundant_assume_align_1(ptr %p) {
189199
define ptr @redundant_assume_align_8_via_align_metadata(ptr %p) {
190200
; CHECK-LABEL: @redundant_assume_align_8_via_align_metadata(
191201
; 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) ]
193202
; CHECK-NEXT: call void @foo(ptr [[P2]])
194203
; CHECK-NEXT: ret ptr [[P2]]
195204
;
@@ -249,7 +258,48 @@ define ptr @redundant_assume_align_8_via_asume(ptr %p) {
249258
ret ptr %p
250259
}
251260

261+
define void @redundant_arg_passed_to_intrinsic(ptr %dst, ptr %src) {
262+
; CHECK-LABEL: @redundant_arg_passed_to_intrinsic(
263+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[DST:%.*]], i32 8) ]
264+
; CHECK-NEXT: call void @bar()
265+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[SRC:%.*]], i32 8) ]
266+
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) [[DST]], ptr noundef nonnull align 8 dereferenceable(16) [[SRC]], i64 16, i1 false)
267+
; CHECK-NEXT: ret void
268+
;
269+
call void @llvm.assume(i1 true) [ "align"(ptr %dst, i32 8) ]
270+
call void @bar()
271+
call void @llvm.assume(i1 true) [ "align"(ptr %src, i32 8) ]
272+
call void @llvm.memmove.p0.p0.i64(ptr align 8 %dst, ptr %src, i64 16, i1 false)
273+
ret void
274+
}
275+
276+
define void @test_store(ptr %ptr) {
277+
; CHECK-LABEL: @test_store(
278+
; CHECK-NEXT: entry:
279+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR:%.*]], i64 2) ]
280+
; CHECK-NEXT: store i16 0, ptr [[PTR]], align 1
281+
; CHECK-NEXT: ret void
282+
;
283+
entry:
284+
call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i64 2) ]
285+
store i16 0, ptr %ptr, align 1
286+
ret void
287+
}
288+
252289
declare void @foo(ptr)
290+
declare void @bar()
291+
292+
; !align must have a constant integer alignment.
293+
define ptr @dont_fold_assume_align_not_constant_of_loaded_pointer_into_align_metadata(ptr %p, i64 %align) {
294+
; CHECK-LABEL: @dont_fold_assume_align_not_constant_of_loaded_pointer_into_align_metadata(
295+
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
296+
; CHECK-NEXT: ret ptr [[P2]]
297+
;
298+
%p2 = load ptr, ptr %p
299+
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 %align) ]
300+
ret ptr %p2
301+
}
302+
253303
;.
254304
; CHECK: [[META0]] = !{i64 8}
255305
;.

llvm/test/Transforms/InstCombine/assume.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt < %s -passes=instcombine -S | FileCheck --check-prefixes=CHECK,DEFAULT %s
3-
; RUN: opt < %s -passes=instcombine --enable-knowledge-retention -S | FileCheck --check-prefixes=CHECK,BUNDLES %s
2+
; RUN: opt < %s -passes='instcombine<no-verify-fixpoint>' -S | FileCheck --check-prefixes=CHECK,DEFAULT %s
3+
; RUN: opt < %s -passes='instcombine<no-verify-fixpoint>' --enable-knowledge-retention -S | FileCheck --check-prefixes=CHECK,BUNDLES %s
44

5-
; RUN: opt < %s -passes=instcombine -S --try-experimental-debuginfo-iterators | FileCheck --check-prefixes=CHECK,DEFAULT %s
6-
; RUN: opt < %s -passes=instcombine --enable-knowledge-retention -S --try-experimental-debuginfo-iterators | FileCheck --check-prefixes=CHECK,BUNDLES %s
5+
; RUN: opt < %s -passes='instcombine<no-verify-fixpoint>' -S --try-experimental-debuginfo-iterators | FileCheck --check-prefixes=CHECK,DEFAULT %s
6+
; RUN: opt < %s -passes='instcombine<no-verify-fixpoint>' --enable-knowledge-retention -S --try-experimental-debuginfo-iterators | FileCheck --check-prefixes=CHECK,BUNDLES %s
77

88
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
99
target triple = "x86_64-unknown-linux-gnu"

0 commit comments

Comments
 (0)