Handle IntToPtr in isBytewiseValue

Summary:
This helps with more efficient use of memset for pattern initialization

From @pcc prototype for -ftrivial-auto-var-init=pattern optimizations

Binary size change on CTMark, (with -fuse-ld=lld -Wl,--icf=all, similar results with default linker options)
```
                   master           patch      diff
Os           8.238864e+05    8.238864e+05       0.0
O3           1.054797e+06    1.054797e+06       0.0
Os zero      8.292384e+05    8.292384e+05       0.0
O3 zero      1.062626e+06    1.062626e+06       0.0
Os pattern   8.579712e+05    8.338048e+05 -0.030299
O3 pattern   1.090502e+06    1.067574e+06 -0.020481
```

Zero vs Pattern on master
```
               zero       pattern      diff
Os     8.292384e+05  8.579712e+05  0.036578
O3     1.062626e+06  1.090502e+06  0.025124
```

Zero vs Pattern with the patch
```
               zero       pattern      diff
Os     8.292384e+05  8.338048e+05  0.003333
O3     1.062626e+06  1.067574e+06  0.003193
```

Reviewers: pcc, eugenis

Subscribers: hiraditya, cfe-commits, llvm-commits

Tags: #clang, #llvm

Differential Revision: https://reviews.llvm.org/D63967

llvm-svn: 365858
This commit is contained in:
Vitaly Buka 2019-07-12 01:42:03 +00:00
parent 669ad5ff15
commit c559e63798
3 changed files with 16 additions and 11 deletions

View File

@ -1042,14 +1042,8 @@ TEST_UNINIT(intptr4, int*[4]);
// CHECK: %uninit = alloca [4 x i32*], align // CHECK: %uninit = alloca [4 x i32*], align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit) // CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-O1-LABEL: @test_intptr4_uninit() // PATTERN-O1-LABEL: @test_intptr4_uninit()
// PATTERN-O1: %1 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 0 // PATTERN-O1: %1 = bitcast [4 x i32*]* %uninit to i8*
// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %1, align 16 // PATTERN-O1-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 16 %1, i8 -86, i64 32, i1 false)
// PATTERN-O1-NEXT: %2 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 1
// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %2, align 8
// PATTERN-O1-NEXT: %3 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 2
// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %3, align 16
// PATTERN-O1-NEXT: %4 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 3
// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %4, align 8
// ZERO-LABEL: @test_intptr4_uninit() // ZERO-LABEL: @test_intptr4_uninit()
// ZERO: call void @llvm.memset{{.*}}, i8 0, // ZERO: call void @llvm.memset{{.*}}, i8 0,

View File

@ -3218,6 +3218,17 @@ Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) {
} }
} }
if (auto *CE = dyn_cast<ConstantExpr>(C)) {
if (CE->getOpcode() == Instruction::IntToPtr) {
auto PS = DL.getPointerSizeInBits(
cast<PointerType>(CE->getType())->getAddressSpace());
return isBytewiseValue(
ConstantExpr::getIntegerCast(CE->getOperand(0),
Type::getIntNTy(Ctx, PS), false),
DL);
}
}
auto Merge = [&](Value *LHS, Value *RHS) -> Value * { auto Merge = [&](Value *LHS, Value *RHS) -> Value * {
if (LHS == RHS) if (LHS == RHS)
return LHS; return LHS;

View File

@ -794,11 +794,11 @@ const std::pair<const char *, const char *> IsBytewiseValueTests[] = {
"i16* inttoptr (i64 0 to i16*)", "i16* inttoptr (i64 0 to i16*)",
}, },
{ {
"", "i8 -1",
"i16* inttoptr (i64 -1 to i16*)", "i16* inttoptr (i64 -1 to i16*)",
}, },
{ {
"", "i8 -86",
"i16* inttoptr (i64 -6148914691236517206 to i16*)", "i16* inttoptr (i64 -6148914691236517206 to i16*)",
}, },
{ {
@ -806,7 +806,7 @@ const std::pair<const char *, const char *> IsBytewiseValueTests[] = {
"i16* inttoptr (i48 -1 to i16*)", "i16* inttoptr (i48 -1 to i16*)",
}, },
{ {
"", "i8 -1",
"i16* inttoptr (i96 -1 to i16*)", "i16* inttoptr (i96 -1 to i16*)",
}, },
{ {