Skip to content

Commit 5d5cd6b

Browse files
committed
review
1 parent ec806c9 commit 5d5cd6b

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
@@ -3244,7 +3244,7 @@ static bool isRemovableWrite(CallBase &CB, Value *UsedV,
32443244
return Dest && Dest->Ptr == UsedV;
32453245
}
32463246

3247-
static bool isAllocSiteRemovable(Instruction *AI,
3247+
static std::optional<ModRefInfo> isAllocSiteRemovable(Instruction *AI,
32483248
SmallVectorImpl<WeakTrackingVH> &Users,
32493249
const TargetLibraryInfo &TLI, bool KnowInit) {
32503250
SmallVector<Instruction*, 4> Worklist;
@@ -3259,7 +3259,7 @@ static bool isAllocSiteRemovable(Instruction *AI,
32593259
switch (I->getOpcode()) {
32603260
default:
32613261
// Give up the moment we see something we can't handle.
3262-
return false;
3262+
return std::nullopt;
32633263

32643264
case Instruction::AddrSpaceCast:
32653265
case Instruction::BitCast:
@@ -3274,10 +3274,10 @@ static bool isAllocSiteRemovable(Instruction *AI,
32743274
// We also fold comparisons in some conditions provided the alloc has
32753275
// not escaped (see isNeverEqualToUnescapedAlloc).
32763276
if (!ICI->isEquality())
3277-
return false;
3277+
return std::nullopt;
32783278
unsigned OtherIndex = (ICI->getOperand(0) == PI) ? 1 : 0;
32793279
if (!isNeverEqualToUnescapedAlloc(ICI->getOperand(OtherIndex), TLI, AI))
3280-
return false;
3280+
return std::nullopt;
32813281

32823282
// Do not fold compares to aligned_alloc calls, as they may have to
32833283
// return null in case the required alignment cannot be satisfied,
@@ -3297,7 +3297,7 @@ static bool isAllocSiteRemovable(Instruction *AI,
32973297
if (CB && TLI.getLibFunc(*CB->getCalledFunction(), TheLibFunc) &&
32983298
TLI.has(TheLibFunc) && TheLibFunc == LibFunc_aligned_alloc &&
32993299
!AlignmentAndSizeKnownValid(CB))
3300-
return false;
3300+
return std::nullopt;
33013301
Users.emplace_back(I);
33023302
continue;
33033303
}
@@ -3307,20 +3307,20 @@ static bool isAllocSiteRemovable(Instruction *AI,
33073307
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
33083308
switch (II->getIntrinsicID()) {
33093309
default:
3310-
return false;
3310+
return std::nullopt;
33113311

33123312
case Intrinsic::memmove:
33133313
case Intrinsic::memcpy:
33143314
case Intrinsic::memset: {
33153315
MemIntrinsic *MI = cast<MemIntrinsic>(II);
33163316
if (MI->isVolatile())
3317-
return false;
3317+
return std::nullopt;
33183318
// Note: this could also be ModRef, but we can still interpret that
33193319
// as just Mod in that case.
33203320
ModRefInfo NewAccess =
33213321
MI->getRawDest() == PI ? ModRefInfo::Mod : ModRefInfo::Ref;
33223322
if ((Access & ~NewAccess) != ModRefInfo::NoModRef)
3323-
return false;
3323+
return std::nullopt;
33243324
Access |= NewAccess;
33253325
}
33263326
[[fallthrough]];
@@ -3360,14 +3360,14 @@ static bool isAllocSiteRemovable(Instruction *AI,
33603360
continue;
33613361
}
33623362

3363-
return false;
3363+
return std::nullopt;
33643364

33653365
case Instruction::Store: {
33663366
StoreInst *SI = cast<StoreInst>(I);
33673367
if (SI->isVolatile() || SI->getPointerOperand() != PI)
3368-
return false;
3368+
return std::nullopt;
33693369
if (isRefSet(Access))
3370-
return false;
3370+
return std::nullopt;
33713371
Access |= ModRefInfo::Mod;
33723372
Users.emplace_back(I);
33733373
continue;
@@ -3376,9 +3376,9 @@ static bool isAllocSiteRemovable(Instruction *AI,
33763376
case Instruction::Load: {
33773377
LoadInst *LI = cast<LoadInst>(I);
33783378
if (LI->isVolatile() || LI->getPointerOperand() != PI)
3379-
return false;
3379+
return std::nullopt;
33803380
if (isModSet(Access))
3381-
return false;
3381+
return std::nullopt;
33823382
Access |= ModRefInfo::Ref;
33833383
Users.emplace_back(I);
33843384
continue;
@@ -3388,7 +3388,8 @@ static bool isAllocSiteRemovable(Instruction *AI,
33883388
}
33893389
} while (!Worklist.empty());
33903390

3391-
return true;
3391+
assert(Access != ModRefInfo::ModRef);
3392+
return Access;
33923393
}
33933394

33943395
Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
@@ -3418,20 +3419,25 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
34183419

34193420
// Determine what getInitialValueOfAllocation would return without actually
34203421
// allocating the result.
3421-
bool KnowInitUndef = isa<AllocaInst>(MI);
3422+
bool KnowInitUndef = false;
34223423
bool KnowInitZero = false;
3423-
if (!KnowInitUndef) {
3424-
Constant *Init = getInitialValueOfAllocation(
3425-
&MI, &TLI, Type::getInt8Ty(MI.getContext()));
3426-
if (Init) {
3427-
if (isa<UndefValue>(Init))
3428-
KnowInitUndef = true;
3429-
else if (Init->isNullValue())
3430-
KnowInitZero = true;
3431-
}
3432-
}
3433-
3434-
if (isAllocSiteRemovable(&MI, Users, TLI, KnowInitZero | KnowInitUndef)) {
3424+
Constant *Init = getInitialValueOfAllocation(
3425+
&MI, &TLI, Type::getInt8Ty(MI.getContext()));
3426+
if (Init) {
3427+
if (isa<UndefValue>(Init))
3428+
KnowInitUndef = true;
3429+
else if (Init->isNullValue())
3430+
KnowInitZero = true;
3431+
}
3432+
// The various sanitizers don't actually return undef memory, but rather
3433+
// memory initialized with special forms of runtime poison
3434+
auto &F = *MI.getFunction();
3435+
if (F.hasFnAttribute(Attribute::SanitizeMemory) ||
3436+
F.hasFnAttribute(Attribute::SanitizeAddress))
3437+
KnowInitUndef = false;
3438+
3439+
auto Removable = isAllocSiteRemovable(&MI, Users, TLI, KnowInitZero | KnowInitUndef);
3440+
if (Removable) {
34353441
for (unsigned i = 0, e = Users.size(); i != e; ++i) {
34363442
// Lowering all @llvm.objectsize and MTI calls first because they may use
34373443
// a bitcast/GEP of the alloca we are removing.
@@ -3452,14 +3458,14 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
34523458
Users[i] = nullptr; // Skip examining in the next loop.
34533459
}
34543460
if (auto *MTI = dyn_cast<MemTransferInst>(I)) {
3455-
if (KnowInitZero && getUnderlyingObject(MTI->getRawDest()) != &MI) {
3461+
if (KnowInitZero && isRefSet(*Removable)) {
34563462
IRBuilderBase::InsertPointGuard Guard(Builder);
34573463
Builder.SetInsertPoint(MTI);
34583464
auto *M = Builder.CreateMemSet(
34593465
MTI->getRawDest(),
34603466
ConstantInt::get(Type::getInt8Ty(MI.getContext()), 0),
34613467
MTI->getLength(), MTI->getDestAlign());
3462-
M->copyMetadata(*MTI, LLVMContext::MD_DIAssignID);
3468+
M->copyMetadata(*MTI);
34633469
}
34643470
}
34653471
}

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)