llvm.org GIT mirror llvm / 3fdfffb
GVN: Enable value forwarding for calloc Enable value forwarding for loads from `calloc()` without an intervening store. This change extends GVN to handle the following case: %1 = tail call noalias i8* @calloc(i64 1, i64 4) %2 = bitcast i8* %1 to i32* ; This load is trivially constant zero %3 = load i32* %2, align 4 This is analogous to the handling for `malloc()` in the same places. `malloc()` returns `undef`; `calloc()` returns a zero value. Note that it is correct to return zero even for out of bounds GEPs since the result of such a GEP would be undefined. Patch by Philip Reames! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210828 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 5 years ago
2 changed file(s) with 41 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
14631463 continue;
14641464 }
14651465
1466 // Loading from calloc (which zero initializes memory) -> zero
1467 if (isCallocLikeFn(DepInst, TLI)) {
1468 ValuesPerBlock.push_back(AvailableValueInBlock::get(
1469 DepBB, Constant::getNullValue(LI->getType())));
1470 continue;
1471 }
1472
14661473 if (StoreInst *S = dyn_cast(DepInst)) {
14671474 // Reject loads and stores that are to the same address but are of
14681475 // different types if we have to.
19871994 }
19881995 }
19891996
1997 // If this load follows a calloc (which zero initializes memory),
1998 // then the loaded value is zero
1999 if (isCallocLikeFn(DepInst, TLI)) {
2000 L->replaceAllUsesWith(Constant::getNullValue(L->getType()));
2001 markInstructionForDeletion(L);
2002 ++NumGVNLoad;
2003 return true;
2004 }
2005
19902006 return false;
19912007 }
19922008
0 ; RUN: opt -S -basicaa -gvn < %s | FileCheck %s
1 ; RUN: opt -S -basicaa -gvn -disable-simplify-libcalls < %s | FileCheck %s -check-prefix=CHECK_NO_LIBCALLS
2 ; Check that loads from calloc are recognized as being zero.
3
4 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
5
6 ; Function Attrs: nounwind uwtable
7 define i32 @test1() {
8 %1 = tail call noalias i8* @calloc(i64 1, i64 4)
9 %2 = bitcast i8* %1 to i32*
10 ; This load is trivially constant zero
11 %3 = load i32* %2, align 4
12 ret i32 %3
13
14 ; CHECK-LABEL: @test1(
15 ; CHECK-NOT: %3 = load i32* %2, align 4
16 ; CHECK: ret i32 0
17
18 ; CHECK_NO_LIBCALLS-LABEL: @test1(
19 ; CHECK_NO_LIBCALLS: load
20 ; CHECK_NO_LIBCALLS: ret i32 %
21
22 }
23
24 declare noalias i8* @calloc(i64, i64)