Index: llvm/lib/Analysis/MemoryBuiltins.cpp =================================================================== --- llvm/lib/Analysis/MemoryBuiltins.cpp +++ llvm/lib/Analysis/MemoryBuiltins.cpp @@ -559,6 +559,12 @@ IRBuilder Builder(Ctx, TargetFolder(DL)); Builder.SetInsertPoint(ObjectSize); + // A non-constant size expression cannot evaluate to -1. + if (!isa(SizeOffsetPair.first) || + !isa(SizeOffsetPair.second)) + Builder.CreateAssumption( + Builder.CreateICmpNE(ObjectSize, ConstantInt::get(ResultType, -1))); + // If we've outside the end of the object, then we can always access // exactly 0 bytes. Value *ResultSize = Index: llvm/test/Transforms/InstCombine/builtin-dynamic-object-size.ll =================================================================== --- llvm/test/Transforms/InstCombine/builtin-dynamic-object-size.ll +++ llvm/test/Transforms/InstCombine/builtin-dynamic-object-size.ll @@ -14,7 +14,7 @@ ; CHECK: define i64 @weird_identity_but_ok(i64 %sz) ; CHECK-NEXT: entry: -; CHECK-NEXT: ret i64 %sz +; CHECK: ret i64 %sz ; CHECK-NEXT: } define i64 @phis_are_neat(i1 %which) { @@ -101,6 +101,30 @@ ; CHECK: define void @f() ; CHECK: call i64 @llvm.objectsize.i64.p0i8( +define void @bdos_impl(i64 %alloc) { +entry: + %obj = call i8* @malloc(i64 %alloc) + %objsize = call i64 @llvm.objectsize.i64.p0i8(i8* %obj, i1 0, i1 0, i1 1) + %cmp.not = icmp eq i64 %objsize, -1 + br i1 %cmp.not, label %if.else, label %if.then + +if.then: + call void @fortified_chk(i8* %obj, i64 %alloc) + br label %if.end + +if.else: + call void @unfortified(i8* %obj, i64 %alloc) + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + +; CHECK: define void @bdos_impl( +; CHECK: call void @llvm.assume( +; CHECK: call void @fortified_chk(i8* %obj, i64 %alloc) + + declare void @bury(i32) local_unnamed_addr #2 ; Function Attrs: nounwind allocsize(0) @@ -113,3 +137,7 @@ ; Function Attrs: nounwind readnone speculatable declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1) + +declare void @fortified_chk(i8*, i64) + +declare void @unfortified(i8*, i64) Index: llvm/test/Transforms/InstCombine/limit-max-iterations.ll =================================================================== --- llvm/test/Transforms/InstCombine/limit-max-iterations.ll +++ llvm/test/Transforms/InstCombine/limit-max-iterations.ll @@ -1,8 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -instcombine --instcombine-max-iterations=0 -S | FileCheck %s --check-prefix=ZERO -; RUN: opt < %s -instcombine --instcombine-max-iterations=1 -S | FileCheck %s --check-prefix=ONE ; RUN: opt < %s -instcombine -S | FileCheck %s --check-prefix=FIXPOINT -; RUN: not --crash opt < %s -instcombine -S --instcombine-infinite-loop-threshold=2 2>&1 | FileCheck %s --check-prefix=LOOP +; RUN: not --crash opt < %s -instcombine -S --instcombine-infinite-loop-threshold=1 2>&1 | FileCheck %s --check-prefix=LOOP ; Based on builtin-dynamic-object-size.ll. This requires multiple iterations of ; InstCombine to reach a fixpoint. @@ -15,18 +14,13 @@ ; ZERO-NEXT: tail call void @free(i8* [[CALL]]) ; ZERO-NEXT: ret i64 [[CALC_SIZE]] ; -; ONE-LABEL: @weird_identity_but_ok( -; ONE-NEXT: entry: -; ONE-NEXT: [[TMP0:%.*]] = sub i64 [[SZ:%.*]], 0 -; ONE-NEXT: [[TMP1:%.*]] = icmp ult i64 [[SZ]], 0 -; ONE-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP0]] -; ONE-NEXT: ret i64 [[TMP2]] -; ; FIXPOINT-LABEL: @weird_identity_but_ok( ; FIXPOINT-NEXT: entry: -; FIXPOINT-NEXT: ret i64 [[SZ:%.*]] +; FIXPOINT-NEXT: [[TMP:%.*]] = icmp ne i64 [[SZ:%.*]], -1 +; FIXPOINT-NEXT: call void @llvm.assume(i1 [[TMP]]) +; FIXPOINT-NEXT: ret i64 [[SZ]] ; -; LOOP: LLVM ERROR: Instruction Combining seems stuck in an infinite loop after 2 iterations. +; LOOP: LLVM ERROR: Instruction Combining seems stuck in an infinite loop after 1 iterations. entry: %call = tail call i8* @malloc(i64 %sz) %calc_size = tail call i64 @llvm.objectsize.i64.p0i8(i8* %call, i1 false, i1 true, i1 true)