Skip to content

Commit dcbc91f

Browse files
committed
[instcombine] Delete duplicate object size logic
nstCombine appears to duplicate the allocation size logic used inside getObjectSize when figuring out which attributes are safe to place on the callsite. We can use the existing utility function instead. The test change is correct. With aligned_alloc, a zero alignment is required to return nullptr. As such, deref_or_null is a correct attribute to use. Differential Revision: https://reviews.llvm.org/D116816
1 parent 68defc0 commit dcbc91f

File tree

2 files changed

+21
-47
lines changed

2 files changed

+21
-47
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 20 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2571,57 +2571,31 @@ static IntrinsicInst *findInitTrampoline(Value *Callee) {
25712571
}
25722572

25732573
void InstCombinerImpl::annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI) {
2574-
unsigned NumArgs = Call.arg_size();
2575-
ConstantInt *Op0C = dyn_cast<ConstantInt>(Call.getOperand(0));
2576-
ConstantInt *Op1C =
2577-
(NumArgs == 1) ? nullptr : dyn_cast<ConstantInt>(Call.getOperand(1));
2578-
// Bail out if the allocation size is zero (or an invalid alignment of zero
2579-
// with aligned_alloc).
2580-
if ((Op0C && Op0C->isNullValue()) || (Op1C && Op1C->isNullValue()))
2581-
return;
25822574

2583-
if (isMallocLikeFn(&Call, TLI) && Op0C) {
2575+
uint64_t Size;
2576+
ObjectSizeOpts Opts;
2577+
if (getObjectSize(&Call, Size, DL, TLI, Opts) && Size > 0) {
2578+
// TODO: should be annotating these nonnull
25842579
if (isOpNewLikeFn(&Call, TLI))
25852580
Call.addRetAttr(Attribute::getWithDereferenceableBytes(
2586-
Call.getContext(), Op0C->getZExtValue()));
2581+
Call.getContext(), Size));
25872582
else
25882583
Call.addRetAttr(Attribute::getWithDereferenceableOrNullBytes(
2589-
Call.getContext(), Op0C->getZExtValue()));
2590-
} else if (isAlignedAllocLikeFn(&Call, TLI)) {
2591-
if (Op1C)
2592-
Call.addRetAttr(Attribute::getWithDereferenceableOrNullBytes(
2593-
Call.getContext(), Op1C->getZExtValue()));
2594-
// Add alignment attribute if alignment is a power of two constant.
2595-
if (Op0C && Op0C->getValue().ult(llvm::Value::MaximumAlignment) &&
2596-
isKnownNonZero(Call.getOperand(1), DL, 0, &AC, &Call, &DT)) {
2597-
uint64_t AlignmentVal = Op0C->getZExtValue();
2598-
if (llvm::isPowerOf2_64(AlignmentVal)) {
2599-
Call.removeRetAttr(Attribute::Alignment);
2600-
Call.addRetAttr(Attribute::getWithAlignment(Call.getContext(),
2601-
Align(AlignmentVal)));
2602-
}
2603-
}
2604-
} else if (isReallocLikeFn(&Call, TLI) && Op1C) {
2605-
Call.addRetAttr(Attribute::getWithDereferenceableOrNullBytes(
2606-
Call.getContext(), Op1C->getZExtValue()));
2607-
} else if (isCallocLikeFn(&Call, TLI) && Op0C && Op1C) {
2608-
bool Overflow;
2609-
const APInt &N = Op0C->getValue();
2610-
APInt Size = N.umul_ov(Op1C->getValue(), Overflow);
2611-
if (!Overflow)
2612-
Call.addRetAttr(Attribute::getWithDereferenceableOrNullBytes(
2613-
Call.getContext(), Size.getZExtValue()));
2614-
} else if (isStrdupLikeFn(&Call, TLI)) {
2615-
uint64_t Len = GetStringLength(Call.getOperand(0));
2616-
if (Len) {
2617-
// strdup
2618-
if (NumArgs == 1)
2619-
Call.addRetAttr(Attribute::getWithDereferenceableOrNullBytes(
2620-
Call.getContext(), Len));
2621-
// strndup
2622-
else if (NumArgs == 2 && Op1C)
2623-
Call.addRetAttr(Attribute::getWithDereferenceableOrNullBytes(
2624-
Call.getContext(), std::min(Len, Op1C->getZExtValue() + 1)));
2584+
Call.getContext(), Size));
2585+
}
2586+
2587+
// Add alignment attribute if alignment is a power of two constant.
2588+
if (!isAlignedAllocLikeFn(&Call, TLI))
2589+
return;
2590+
2591+
ConstantInt *Op0C = dyn_cast<ConstantInt>(Call.getOperand(0));
2592+
if (Op0C && Op0C->getValue().ult(llvm::Value::MaximumAlignment) &&
2593+
isKnownNonZero(Call.getOperand(1), DL, 0, &AC, &Call, &DT)) {
2594+
uint64_t AlignmentVal = Op0C->getZExtValue();
2595+
if (llvm::isPowerOf2_64(AlignmentVal)) {
2596+
Call.removeRetAttr(Attribute::Alignment);
2597+
Call.addRetAttr(Attribute::getWithAlignment(Call.getContext(),
2598+
Align(AlignmentVal)));
26252599
}
26262600
}
26272601
}

llvm/test/Transforms/InstCombine/deref-alloc-fns.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ declare noalias i8* @foo(i8*, i8*, i8*)
7777
define noalias i8* @aligned_alloc_dynamic_args(i64 %align, i64 %size) {
7878
; CHECK-LABEL: @aligned_alloc_dynamic_args(
7979
; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(1024) i8* @aligned_alloc(i64 [[ALIGN:%.*]], i64 1024)
80-
; CHECK-NEXT: [[CALL_1:%.*]] = tail call noalias i8* @aligned_alloc(i64 0, i64 1024)
80+
; CHECK-NEXT: [[CALL_1:%.*]] = tail call noalias dereferenceable_or_null(1024) i8* @aligned_alloc(i64 0, i64 1024)
8181
; CHECK-NEXT: [[CALL_2:%.*]] = tail call noalias i8* @aligned_alloc(i64 32, i64 [[SIZE:%.*]])
8282
; CHECK-NEXT: [[TMP1:%.*]] = call i8* @foo(i8* [[CALL]], i8* [[CALL_1]], i8* [[CALL_2]])
8383
; CHECK-NEXT: ret i8* [[CALL]]

0 commit comments

Comments
 (0)