Skip to content

Commit

Permalink
[InstCombine] Fold IntToPtr and PtrToInt into preceding loads.
Browse files Browse the repository at this point in the history
Currently we only fold a BitCast into a Load when the BitCast is its
only user.

Do the same for any no-op cast.

Differential Revision: http://reviews.llvm.org/D9152

llvm-svn: 238452
  • Loading branch information
majnemer committed May 28, 2015
1 parent d804a1e commit dd04352
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 5 deletions.
15 changes: 10 additions & 5 deletions llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
Expand Up @@ -483,12 +483,17 @@ static Instruction *combineLoadToOperationType(InstCombiner &IC, LoadInst &LI) {
}

// Fold away bit casts of the loaded value by loading the desired type.
// We can do this for BitCastInsts as well as casts from and to pointer types,
// as long as those are noops (i.e., the source or dest type have the same
// bitwidth as the target's pointers).
if (LI.hasOneUse())
if (auto *BC = dyn_cast<BitCastInst>(LI.user_back())) {
LoadInst *NewLoad = combineLoadToNewType(IC, LI, BC->getDestTy());
BC->replaceAllUsesWith(NewLoad);
IC.EraseInstFromFunction(*BC);
return &LI;
if (auto* CI = dyn_cast<CastInst>(LI.user_back())) {
if (CI->isNoopCast(DL)) {
LoadInst *NewLoad = combineLoadToNewType(IC, LI, CI->getDestTy());
CI->replaceAllUsesWith(NewLoad);
IC.EraseInstFromFunction(*CI);
return &LI;
}
}

// FIXME: We should also canonicalize loads of vectors when their elements are
Expand Down
79 changes: 79 additions & 0 deletions llvm/test/Transforms/InstCombine/load-bitcast32.ll
@@ -0,0 +1,79 @@
; RUN: opt -instcombine -S < %s | FileCheck %s

target datalayout = "p:32:32:32"


define i64* @test1(i8* %x) {
entry:
; CHECK-LABEL: @test1(
; CHECK: load i64, i64*
; CHECK: ret
%a = bitcast i8* %x to i64*
%b = load i64, i64* %a
%c = inttoptr i64 %b to i64*

ret i64* %c
}

define i32* @test2(i8* %x) {
entry:
; CHECK-LABEL: @test2(
; CHECK: load i32*, i32**
; CHECK: ret
%a = bitcast i8* %x to i32*
%b = load i32, i32* %a
%c = inttoptr i32 %b to i32*

ret i32* %c
}

define i64* @test3(i8* %x) {
entry:
; CHECK-LABEL: @test3(
; CHECK: load i64*, i64**
; CHECK: ret
%a = bitcast i8* %x to i32*
%b = load i32, i32* %a
%c = inttoptr i32 %b to i64*

ret i64* %c
}

define i64 @test4(i8* %x) {
entry:
; CHECK-LABEL: @test4(
; CHECK: load i32, i32*
; CHECK: zext
; CHECK: ret
%a = bitcast i8* %x to i64**
%b = load i64*, i64** %a
%c = ptrtoint i64* %b to i64

ret i64 %c
}

define i32 @test5(i8* %x) {
entry:
; CHECK-LABEL: @test5(
; CHECK: load i32, i32*
; CHECK: ret
%a = bitcast i8* %x to i32**
%b = load i32*, i32** %a
%c = ptrtoint i32* %b to i32

ret i32 %c
}

define i64 @test6(i8* %x) {
entry:
; CHECK-LABEL: @test6(
; CHECK: load i32, i32*
; CHECK: zext
; CHECK: ret
%a = bitcast i8* %x to i32**
%b = load i32*, i32** %a
%c = ptrtoint i32* %b to i64

ret i64 %c
}

78 changes: 78 additions & 0 deletions llvm/test/Transforms/InstCombine/load-bitcast64.ll
@@ -0,0 +1,78 @@
; RUN: opt -instcombine -S < %s | FileCheck %s

target datalayout = "p:64:64:64"


define i64* @test1(i8* %x) {
entry:
; CHECK-LABEL: @test1(
; CHECK: load i64*, i64**
; CHECK: ret
%a = bitcast i8* %x to i64*
%b = load i64, i64* %a
%c = inttoptr i64 %b to i64*

ret i64* %c
}

define i32* @test2(i8* %x) {
entry:
; CHECK-LABEL: @test2(
; CHECK: load i32, i32*
; CHECK: ret
%a = bitcast i8* %x to i32*
%b = load i32, i32* %a
%c = inttoptr i32 %b to i32*

ret i32* %c
}

define i64* @test3(i8* %x) {
entry:
; CHECK-LABEL: @test3(
; CHECK: load i32, i32*
; CHECK: ret
%a = bitcast i8* %x to i32*
%b = load i32, i32* %a
%c = inttoptr i32 %b to i64*

ret i64* %c
}

define i64 @test4(i8* %x) {
entry:
; CHECK-LABEL: @test4(
; CHECK: load i64, i64*
; CHECK: ret
%a = bitcast i8* %x to i64**
%b = load i64*, i64** %a
%c = ptrtoint i64* %b to i64

ret i64 %c
}

define i32 @test5(i8* %x) {
entry:
; CHECK-LABEL: @test5(
; CHECK: load i64, i64*
; CHECK: trunc
; CHECK: ret
%a = bitcast i8* %x to i32**
%b = load i32*, i32** %a
%c = ptrtoint i32* %b to i32

ret i32 %c
}

define i64 @test6(i8* %x) {
entry:
; CHECK-LABEL: @test6(
; CHECK: load i64, i64*
; CHECK: ret
%a = bitcast i8* %x to i32**
%b = load i32*, i32** %a
%c = ptrtoint i32* %b to i64

ret i64 %c
}

0 comments on commit dd04352

Please sign in to comment.