Skip to content

Commit 097ffe3

Browse files
committed
review
1 parent 6e5332d commit 097ffe3

File tree

3 files changed

+101
-92
lines changed

3 files changed

+101
-92
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3277,7 +3277,7 @@ static bool isRemovableWrite(CallBase &CB, Value *UsedV,
32773277
return Dest && Dest->Ptr == UsedV;
32783278
}
32793279

3280-
static bool isAllocSiteRemovable(Instruction *AI,
3280+
static std::optional<ModRefInfo> isAllocSiteRemovable(Instruction *AI,
32813281
SmallVectorImpl<WeakTrackingVH> &Users,
32823282
const TargetLibraryInfo &TLI, bool KnowInit) {
32833283
SmallVector<Instruction*, 4> Worklist;
@@ -3292,7 +3292,7 @@ static bool isAllocSiteRemovable(Instruction *AI,
32923292
switch (I->getOpcode()) {
32933293
default:
32943294
// Give up the moment we see something we can't handle.
3295-
return false;
3295+
return std::nullopt;
32963296

32973297
case Instruction::AddrSpaceCast:
32983298
case Instruction::BitCast:
@@ -3307,10 +3307,10 @@ static bool isAllocSiteRemovable(Instruction *AI,
33073307
// We also fold comparisons in some conditions provided the alloc has
33083308
// not escaped (see isNeverEqualToUnescapedAlloc).
33093309
if (!ICI->isEquality())
3310-
return false;
3310+
return std::nullopt;
33113311
unsigned OtherIndex = (ICI->getOperand(0) == PI) ? 1 : 0;
33123312
if (!isNeverEqualToUnescapedAlloc(ICI->getOperand(OtherIndex), TLI, AI))
3313-
return false;
3313+
return std::nullopt;
33143314

33153315
// Do not fold compares to aligned_alloc calls, as they may have to
33163316
// return null in case the required alignment cannot be satisfied,
@@ -3330,7 +3330,7 @@ static bool isAllocSiteRemovable(Instruction *AI,
33303330
if (CB && TLI.getLibFunc(*CB->getCalledFunction(), TheLibFunc) &&
33313331
TLI.has(TheLibFunc) && TheLibFunc == LibFunc_aligned_alloc &&
33323332
!AlignmentAndSizeKnownValid(CB))
3333-
return false;
3333+
return std::nullopt;
33343334
Users.emplace_back(I);
33353335
continue;
33363336
}
@@ -3340,20 +3340,20 @@ static bool isAllocSiteRemovable(Instruction *AI,
33403340
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
33413341
switch (II->getIntrinsicID()) {
33423342
default:
3343-
return false;
3343+
return std::nullopt;
33443344

33453345
case Intrinsic::memmove:
33463346
case Intrinsic::memcpy:
33473347
case Intrinsic::memset: {
33483348
MemIntrinsic *MI = cast<MemIntrinsic>(II);
33493349
if (MI->isVolatile())
3350-
return false;
3350+
return std::nullopt;
33513351
// Note: this could also be ModRef, but we can still interpret that
33523352
// as just Mod in that case.
33533353
ModRefInfo NewAccess =
33543354
MI->getRawDest() == PI ? ModRefInfo::Mod : ModRefInfo::Ref;
33553355
if ((Access & ~NewAccess) != ModRefInfo::NoModRef)
3356-
return false;
3356+
return std::nullopt;
33573357
Access |= NewAccess;
33583358
}
33593359
[[fallthrough]];
@@ -3393,14 +3393,14 @@ static bool isAllocSiteRemovable(Instruction *AI,
33933393
continue;
33943394
}
33953395

3396-
return false;
3396+
return std::nullopt;
33973397

33983398
case Instruction::Store: {
33993399
StoreInst *SI = cast<StoreInst>(I);
34003400
if (SI->isVolatile() || SI->getPointerOperand() != PI)
3401-
return false;
3401+
return std::nullopt;
34023402
if (isRefSet(Access))
3403-
return false;
3403+
return std::nullopt;
34043404
Access |= ModRefInfo::Mod;
34053405
Users.emplace_back(I);
34063406
continue;
@@ -3409,9 +3409,9 @@ static bool isAllocSiteRemovable(Instruction *AI,
34093409
case Instruction::Load: {
34103410
LoadInst *LI = cast<LoadInst>(I);
34113411
if (LI->isVolatile() || LI->getPointerOperand() != PI)
3412-
return false;
3412+
return std::nullopt;
34133413
if (isModSet(Access))
3414-
return false;
3414+
return std::nullopt;
34153415
Access |= ModRefInfo::Ref;
34163416
Users.emplace_back(I);
34173417
continue;
@@ -3421,7 +3421,8 @@ static bool isAllocSiteRemovable(Instruction *AI,
34213421
}
34223422
} while (!Worklist.empty());
34233423

3424-
return true;
3424+
assert(Access != ModRefInfo::ModRef);
3425+
return Access;
34253426
}
34263427

34273428
Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
@@ -3451,20 +3452,25 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
34513452

34523453
// Determine what getInitialValueOfAllocation would return without actually
34533454
// allocating the result.
3454-
bool KnowInitUndef = isa<AllocaInst>(MI);
3455+
bool KnowInitUndef = false;
34553456
bool KnowInitZero = false;
3456-
if (!KnowInitUndef) {
3457-
Constant *Init = getInitialValueOfAllocation(
3458-
&MI, &TLI, Type::getInt8Ty(MI.getContext()));
3459-
if (Init) {
3460-
if (isa<UndefValue>(Init))
3461-
KnowInitUndef = true;
3462-
else if (Init->isNullValue())
3463-
KnowInitZero = true;
3464-
}
3465-
}
3466-
3467-
if (isAllocSiteRemovable(&MI, Users, TLI, KnowInitZero | KnowInitUndef)) {
3457+
Constant *Init = getInitialValueOfAllocation(
3458+
&MI, &TLI, Type::getInt8Ty(MI.getContext()));
3459+
if (Init) {
3460+
if (isa<UndefValue>(Init))
3461+
KnowInitUndef = true;
3462+
else if (Init->isNullValue())
3463+
KnowInitZero = true;
3464+
}
3465+
// The various sanitizers don't actually return undef memory, but rather
3466+
// memory initialized with special forms of runtime poison
3467+
auto &F = *MI.getFunction();
3468+
if (F.hasFnAttribute(Attribute::SanitizeMemory) ||
3469+
F.hasFnAttribute(Attribute::SanitizeAddress))
3470+
KnowInitUndef = false;
3471+
3472+
auto Removable = isAllocSiteRemovable(&MI, Users, TLI, KnowInitZero | KnowInitUndef);
3473+
if (Removable) {
34683474
for (unsigned i = 0, e = Users.size(); i != e; ++i) {
34693475
// Lowering all @llvm.objectsize and MTI calls first because they may use
34703476
// a bitcast/GEP of the alloca we are removing.
@@ -3485,14 +3491,14 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
34853491
Users[i] = nullptr; // Skip examining in the next loop.
34863492
}
34873493
if (auto *MTI = dyn_cast<MemTransferInst>(I)) {
3488-
if (KnowInitZero && getUnderlyingObject(MTI->getRawDest()) != &MI) {
3494+
if (KnowInitZero && isRefSet(*Removable)) {
34893495
IRBuilderBase::InsertPointGuard Guard(Builder);
34903496
Builder.SetInsertPoint(MTI);
34913497
auto *M = Builder.CreateMemSet(
34923498
MTI->getRawDest(),
34933499
ConstantInt::get(Type::getInt8Ty(MI.getContext()), 0),
34943500
MTI->getLength(), MTI->getDestAlign());
3495-
M->copyMetadata(*MTI, LLVMContext::MD_DIAssignID);
3501+
M->copyMetadata(*MTI);
34963502
}
34973503
}
34983504
}

llvm/test/Transforms/InstCombine/and-or-icmps.ll

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,72 @@ define void @simplify_before_foldAndOfICmps(ptr %p) {
402402
ret void
403403
}
404404

405+
define void @simplify_before_foldAndOfICmps2(ptr %p, ptr %A8) "instcombine-no-verify-fixpoint" {
406+
; CHECK-LABEL: @simplify_before_foldAndOfICmps2(
407+
; CHECK-NEXT: [[L7:%.*]] = load i16, ptr [[A8:%.*]], align 2
408+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i16 [[L7]], -1
409+
; CHECK-NEXT: [[B11:%.*]] = zext i1 [[TMP1]] to i16
410+
; CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i64
411+
; CHECK-NEXT: [[G4:%.*]] = getelementptr i16, ptr [[A8]], i64 [[TMP2]]
412+
; CHECK-NEXT: [[L2:%.*]] = load i16, ptr [[G4]], align 2
413+
; CHECK-NEXT: [[L4:%.*]] = load i16, ptr [[A8]], align 2
414+
; CHECK-NEXT: [[B21:%.*]] = sdiv i16 [[L7]], [[L4]]
415+
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP1]], i16 [[B21]], i16 0
416+
; CHECK-NEXT: [[B18:%.*]] = sub i16 0, [[TMP5]]
417+
; CHECK-NEXT: [[C11:%.*]] = icmp ugt i16 [[L2]], [[B11]]
418+
; CHECK-NEXT: [[B20:%.*]] = and i16 [[L7]], [[L2]]
419+
; CHECK-NEXT: [[C5:%.*]] = icmp sgt i16 [[B21]], [[L2]]
420+
; CHECK-NEXT: [[C12:%.*]] = icmp ule i16 [[B21]], [[L2]]
421+
; CHECK-NEXT: [[C10:%.*]] = icmp slt i16 [[B20]], 0
422+
; CHECK-NEXT: [[B29:%.*]] = srem i16 [[L4]], [[B18]]
423+
; CHECK-NEXT: [[B15:%.*]] = xor i1 [[C10]], [[C11]]
424+
; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[C12]], [[B15]]
425+
; CHECK-NEXT: [[C6:%.*]] = xor i1 [[TMP6]], true
426+
; CHECK-NEXT: [[B33:%.*]] = or i16 [[B29]], [[L4]]
427+
; CHECK-NEXT: [[C3:%.*]] = and i1 [[C5]], [[C6]]
428+
; CHECK-NEXT: [[C4:%.*]] = and i1 [[C3]], [[C11]]
429+
; CHECK-NEXT: [[TMP4:%.*]] = xor i1 [[C11]], true
430+
; CHECK-NEXT: [[C18:%.*]] = or i1 [[C10]], [[TMP4]]
431+
; CHECK-NEXT: [[TMP3:%.*]] = sext i1 [[C4]] to i64
432+
; CHECK-NEXT: [[G26:%.*]] = getelementptr i1, ptr null, i64 [[TMP3]]
433+
; CHECK-NEXT: store i16 [[B33]], ptr [[P:%.*]], align 2
434+
; CHECK-NEXT: store i1 [[C18]], ptr [[P]], align 1
435+
; CHECK-NEXT: store ptr [[G26]], ptr [[P]], align 8
436+
; CHECK-NEXT: ret void
437+
;
438+
%L7 = load i16, ptr %A8
439+
%G21 = getelementptr i16, ptr %A8, i8 -1
440+
%B11 = udiv i16 %L7, -1
441+
%G4 = getelementptr i16, ptr %A8, i16 %B11
442+
%L2 = load i16, ptr %G4
443+
%L = load i16, ptr %G4
444+
%B23 = mul i16 %B11, %B11
445+
%L4 = load i16, ptr %A8
446+
%B21 = sdiv i16 %L7, %L4
447+
%B7 = sub i16 0, %B21
448+
%B18 = mul i16 %B23, %B7
449+
%C10 = icmp ugt i16 %L, %B11
450+
%B20 = and i16 %L7, %L2
451+
%B1 = mul i1 %C10, true
452+
%C5 = icmp sle i16 %B21, %L
453+
%C11 = icmp ule i16 %B21, %L
454+
%C7 = icmp slt i16 %B20, 0
455+
%B29 = srem i16 %L4, %B18
456+
%B15 = add i1 %C7, %C10
457+
%B19 = add i1 %C11, %B15
458+
%C6 = icmp sge i1 %C11, %B19
459+
%B33 = or i16 %B29, %L4
460+
%C13 = icmp uge i1 %C5, %B1
461+
%C3 = icmp ult i1 %C13, %C6
462+
store i16 undef, ptr %G21
463+
%C18 = icmp ule i1 %C10, %C7
464+
%G26 = getelementptr i1, ptr null, i1 %C3
465+
store i16 %B33, ptr %p
466+
store i1 %C18, ptr %p
467+
store ptr %G26, ptr %p
468+
ret void
469+
}
470+
405471
define i1 @PR42691_1(i32 %x) {
406472
; CHECK-LABEL: @PR42691_1(
407473
; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], 2147483646

llvm/test/Transforms/InstCombine/fixedpoint-and-or-icmps.ll

Lines changed: 0 additions & 63 deletions
This file was deleted.

0 commit comments

Comments
 (0)