Skip to content

Commit 6cca769

Browse files
committed
Step
1 parent 4f80cd7 commit 6cca769

File tree

4 files changed

+118
-21
lines changed

4 files changed

+118
-21
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3242,15 +3242,70 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
32423242
MDNode *MD = MDNode::get(II->getContext(), {});
32433243
LI->setMetadata(LLVMContext::MD_noundef, MD);
32443244
} else {
3245-
// Try to get the instruction before the assumption to use as context.
3246-
Instruction *CtxI = nullptr;
3247-
if (CtxI && II->getParent()->begin() != II->getIterator())
3248-
CtxI = II->getPrevNode();
3249-
3250-
auto Known = computeKnownBits(RK.WasOn, 1, CtxI);
3251-
unsigned KnownAlign = 1 << Known.countMinTrailingZeros();
3252-
if (KnownAlign < RK.ArgValue)
3253-
continue;
3245+
auto *C = dyn_cast<Constant>(RK.WasOn);
3246+
if (C && C->isNullValue()) {
3247+
} else {
3248+
Value *UO = getUnderlyingObject(RK.WasOn);
3249+
3250+
bool CanUseAlign = false;
3251+
SetVector<const Instruction *> WorkList;
3252+
for (const User *U : RK.WasOn->users())
3253+
if (auto *I = dyn_cast<Instruction>(U))
3254+
WorkList.insert(I);
3255+
3256+
for (unsigned I = 0; I != WorkList.size(); ++I) {
3257+
auto *Curr = WorkList[I];
3258+
if (!DT.dominates(II, Curr))
3259+
continue;
3260+
if (auto *LI = dyn_cast<LoadInst>(Curr)) {
3261+
if (LI->getAlign().value() < RK.ArgValue) {
3262+
CanUseAlign = true;
3263+
break;
3264+
}
3265+
continue;
3266+
}
3267+
if (auto *SI = dyn_cast<StoreInst>(Curr)) {
3268+
auto *PtrOpI = dyn_cast<Instruction>(SI->getPointerOperand());
3269+
if (PtrOpI && WorkList.contains(PtrOpI) &&
3270+
SI->getAlign().value() < RK.ArgValue) {
3271+
CanUseAlign = true;
3272+
break;
3273+
}
3274+
continue;
3275+
}
3276+
if (isa<ReturnInst, CallBase>(Curr)) {
3277+
CanUseAlign = true;
3278+
break;
3279+
}
3280+
if (isa<ICmpInst>(Curr) &&
3281+
!isa<Constant>(cast<Instruction>(Curr)->getOperand(0)) &&
3282+
!isa<Constant>(cast<Instruction>(Curr)->getOperand(1))) {
3283+
CanUseAlign = true;
3284+
break;
3285+
}
3286+
if (!Curr->getType()->isPointerTy())
3287+
continue;
3288+
3289+
if (WorkList.size() > 16) {
3290+
CanUseAlign = true;
3291+
break;
3292+
}
3293+
for (const User *U : Curr->users())
3294+
WorkList.insert(cast<Instruction>(U));
3295+
}
3296+
if (CanUseAlign && (!UO || isa<Argument>(UO)))
3297+
continue;
3298+
// Try to get the instruction before the assumption to use as
3299+
// context.
3300+
Instruction *CtxI = nullptr;
3301+
if (CtxI && II->getParent()->begin() != II->getIterator())
3302+
CtxI = II->getPrevNode();
3303+
3304+
auto Known = computeKnownBits(RK.WasOn, 1, CtxI);
3305+
unsigned KnownAlign = 1 << Known.countMinTrailingZeros();
3306+
if (CanUseAlign && KnownAlign < RK.ArgValue)
3307+
continue;
3308+
}
32543309
}
32553310
auto *New = CallBase::removeOperandBundle(II, OBU.getTagID());
32563311
return New;

llvm/lib/Transforms/Scalar/EarlyCSE.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/ADT/Hashing.h"
1717
#include "llvm/ADT/STLExtras.h"
1818
#include "llvm/ADT/ScopedHashTable.h"
19+
#include "llvm/ADT/SetVector.h"
1920
#include "llvm/ADT/SmallVector.h"
2021
#include "llvm/ADT/Statistic.h"
2122
#include "llvm/Analysis/AssumptionCache.h"
@@ -31,6 +32,7 @@
3132
#include "llvm/IR/Constants.h"
3233
#include "llvm/IR/Dominators.h"
3334
#include "llvm/IR/Function.h"
35+
#include "llvm/IR/IRBuilder.h"
3436
#include "llvm/IR/InstrTypes.h"
3537
#include "llvm/IR/Instruction.h"
3638
#include "llvm/IR/Instructions.h"
@@ -1599,6 +1601,25 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
15991601
if (InVal.IsLoad)
16001602
if (auto *I = dyn_cast<Instruction>(Op))
16011603
combineMetadataForCSE(I, &Inst, false);
1604+
1605+
// If the load has align and noundef metadata, preserve it via an
1606+
// alignment assumption. Note that this doesn't use salavageKnowledge,
1607+
// as we need to create the assumption for the value we replaced the
1608+
// load with.
1609+
if (auto *AlignMD = Inst.getMetadata(LLVMContext::MD_align)) {
1610+
if (Inst.hasMetadata(LLVMContext::MD_noundef) ||
1611+
programUndefinedIfPoison(&Inst)) {
1612+
Inst.setMetadata(LLVMContext::MD_align, nullptr);
1613+
auto *B = mdconst::extract<ConstantInt>(AlignMD->getOperand(0));
1614+
auto KB = computeKnownBits(Op, 3, SQ.getWithInstruction(&Inst));
1615+
unsigned AlignFromKB = 1 << KB.countMinTrailingZeros();
1616+
if (AlignFromKB < B->getZExtValue()) {
1617+
IRBuilder Builder(&Inst);
1618+
Builder.CreateAlignmentAssumption(SQ.DL, Op, B);
1619+
}
1620+
}
1621+
}
1622+
16021623
if (!Inst.use_empty())
16031624
Inst.replaceAllUsesWith(Op);
16041625
salvageKnowledge(&Inst, &AC);

llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,8 @@ static void convertMetadataToAssumes(LoadInst *LI, Value *Val,
485485
addAssumeNonNull(AC, LI);
486486

487487
if (AC && LI->getMetadata(LLVMContext::MD_align) &&
488-
LI->getMetadata(LLVMContext::MD_noundef)) {
488+
(LI->getMetadata(LLVMContext::MD_noundef) ||
489+
programUndefinedIfPoison(LI))) {
489490
auto *AlignMD = LI->getMetadata(LLVMContext::MD_align);
490491
auto *B = mdconst::extract<ConstantInt>(AlignMD->getOperand(0));
491492

@@ -494,9 +495,7 @@ static void convertMetadataToAssumes(LoadInst *LI, Value *Val,
494495
if (AlignFromKB < B->getZExtValue()) {
495496
addAssumeAlign(DL, LI, Val);
496497
}
497-
498-
}
499-
498+
}
500499
}
501500

502501
static void removeIntrinsicUsers(AllocaInst *AI) {

llvm/test/Transforms/EarlyCSE/materialize-align-assumptions.ll

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,40 @@
33

44
declare void @foo(ptr)
55

6+
define ptr @align_replacement_does_not_have_align_metadata_missing_noundef(ptr noalias %p) {
7+
; CHECK-LABEL: define ptr @align_replacement_does_not_have_align_metadata_missing_noundef(
8+
; CHECK-SAME: ptr noalias [[P:%.*]]) {
9+
; CHECK-NEXT: [[L_1:%.*]] = load ptr, ptr [[P]], align 8
10+
; CHECK-NEXT: call void @foo(ptr [[L_1]])
11+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[L_1]], i64 4
12+
; CHECK-NEXT: store ptr [[GEP]], ptr [[P]], align 8
13+
; CHECK-NEXT: ret ptr [[GEP]]
14+
;
15+
%l.1 = load ptr, ptr %p, align 8
16+
call void @foo(ptr %l.1)
17+
%l.2 = load ptr, ptr %p, align 8
18+
%gep = getelementptr i8, ptr %l.2, i64 4
19+
store ptr %gep, ptr %p, align 8
20+
%l.3 = load ptr, ptr %p, align 8, !align !0
21+
ret ptr %l.3
22+
}
23+
624
define ptr @align_replacement_does_not_have_align_metadata(ptr noalias %p) {
725
; CHECK-LABEL: define ptr @align_replacement_does_not_have_align_metadata(
826
; CHECK-SAME: ptr noalias [[P:%.*]]) {
927
; CHECK-NEXT: [[L_1:%.*]] = load ptr, ptr [[P]], align 8
1028
; CHECK-NEXT: call void @foo(ptr [[L_1]])
1129
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[L_1]], i64 4
1230
; CHECK-NEXT: store ptr [[GEP]], ptr [[P]], align 8
31+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP]], i64 4) ]
1332
; CHECK-NEXT: ret ptr [[GEP]]
1433
;
1534
%l.1 = load ptr, ptr %p, align 8
1635
call void @foo(ptr %l.1)
1736
%l.2 = load ptr, ptr %p, align 8
1837
%gep = getelementptr i8, ptr %l.2, i64 4
1938
store ptr %gep, ptr %p, align 8
20-
%l.3 = load ptr, ptr %p, align 8, !align !0
39+
%l.3 = load ptr, ptr %p, align 8, !align !0, !noundef !{}
2140
ret ptr %l.3
2241
}
2342

@@ -27,12 +46,13 @@ define ptr @align_replacement_does_not_have_align_metadata2(ptr noalias %p) {
2746
; CHECK-NEXT: [[L_1:%.*]] = load ptr, ptr [[P]], align 8
2847
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[L_1]], i64 4
2948
; CHECK-NEXT: store ptr [[GEP]], ptr [[P]], align 8
49+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP]], i64 4) ]
3050
; CHECK-NEXT: ret ptr [[GEP]]
3151
;
3252
%l.1 = load ptr, ptr %p, align 8
3353
%gep = getelementptr i8, ptr %l.1, i64 4
3454
store ptr %gep, ptr %p, align 8
35-
%l.2 = load ptr, ptr %p, align 8, !align !0
55+
%l.2 = load ptr, ptr %p, align 8, !align !0, !noundef !{}
3656
ret ptr %l.2
3757
}
3858

@@ -54,11 +74,12 @@ define ptr @align_replacement_has_smaller_alignment(ptr noalias %p) {
5474
; CHECK-SAME: ptr noalias [[P:%.*]]) {
5575
; CHECK-NEXT: [[L_1:%.*]] = load ptr, ptr [[P]], align 8, !align [[META0]]
5676
; CHECK-NEXT: call void @foo(ptr [[L_1]])
77+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[L_1]], i64 8) ]
5778
; CHECK-NEXT: ret ptr [[L_1]]
5879
;
5980
%l.1 = load ptr, ptr %p, align 8, !align !0
6081
call void @foo(ptr %l.1)
61-
%l.2 = load ptr, ptr %p, align 8, !align !1
82+
%l.2 = load ptr, ptr %p, align 8, !align !1, !noundef !{}
6283
ret ptr %l.2
6384
}
6485

@@ -67,12 +88,12 @@ define ptr @align_replacement_has_larger_alignment(ptr %p) {
6788
; CHECK-SAME: ptr [[P:%.*]]) {
6889
; CHECK-NEXT: [[L_1:%.*]] = load ptr, ptr [[P]], align 8, !align [[META1:![0-9]+]]
6990
; CHECK-NEXT: call void @foo(ptr [[L_1]])
70-
; CHECK-NEXT: [[L_2:%.*]] = load ptr, ptr [[P]], align 8, !align [[META0]]
91+
; CHECK-NEXT: [[L_2:%.*]] = load ptr, ptr [[P]], align 8, !align [[META0]], !noundef [[META2:![0-9]+]]
7192
; CHECK-NEXT: ret ptr [[L_2]]
7293
;
7394
%l.1 = load ptr, ptr %p, align 8, !align !1
7495
call void @foo(ptr %l.1)
75-
%l.2 = load ptr, ptr %p, align 8, !align !0
96+
%l.2 = load ptr, ptr %p, align 8, !align !0, !noundef !{}
7697
ret ptr %l.2
7798
}
7899

@@ -81,12 +102,12 @@ define ptr @align_1(ptr %p) {
81102
; CHECK-SAME: ptr [[P:%.*]]) {
82103
; CHECK-NEXT: [[L_1:%.*]] = load ptr, ptr [[P]], align 8
83104
; CHECK-NEXT: call void @foo(ptr [[L_1]])
84-
; CHECK-NEXT: [[L_2:%.*]] = load ptr, ptr [[P]], align 8, !align [[META2:![0-9]+]]
105+
; CHECK-NEXT: [[L_2:%.*]] = load ptr, ptr [[P]], align 8, !align [[META3:![0-9]+]], !noundef [[META2]]
85106
; CHECK-NEXT: ret ptr [[L_2]]
86107
;
87108
%l.1 = load ptr, ptr %p, align 8
88109
call void @foo(ptr %l.1)
89-
%l.2 = load ptr, ptr %p, align 8, !align !2
110+
%l.2 = load ptr, ptr %p, align 8, !align !2, !noundef !{}
90111
ret ptr %l.2
91112
}
92113

@@ -96,5 +117,6 @@ define ptr @align_1(ptr %p) {
96117
;.
97118
; CHECK: [[META0]] = !{i64 4}
98119
; CHECK: [[META1]] = !{i64 8}
99-
; CHECK: [[META2]] = !{i64 1}
120+
; CHECK: [[META2]] = !{}
121+
; CHECK: [[META3]] = !{i64 1}
100122
;.

0 commit comments

Comments
 (0)