mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-19 01:48:34 +00:00
Constant-fold ptrtoint+add+inttoptr to gep when the pointer is an
array and the add is within range. This helps simplify expressions expanded by ScalarEvolutionExpander. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71158 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ecb403a9d3
commit
704b6980b8
@ -16,6 +16,7 @@
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/GlobalVariable.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Intrinsics.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
@ -383,12 +384,43 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy,
|
||||
// the int size is >= the ptr size. This requires knowing the width of a
|
||||
// pointer, so it can't be done in ConstantExpr::getCast.
|
||||
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0])) {
|
||||
if (TD && CE->getOpcode() == Instruction::PtrToInt &&
|
||||
if (TD &&
|
||||
TD->getPointerSizeInBits() <=
|
||||
CE->getType()->getPrimitiveSizeInBits()) {
|
||||
Constant *Input = CE->getOperand(0);
|
||||
Constant *C = FoldBitCast(Input, DestTy, *TD);
|
||||
return C ? C : ConstantExpr::getBitCast(Input, DestTy);
|
||||
if (CE->getOpcode() == Instruction::PtrToInt) {
|
||||
Constant *Input = CE->getOperand(0);
|
||||
Constant *C = FoldBitCast(Input, DestTy, *TD);
|
||||
return C ? C : ConstantExpr::getBitCast(Input, DestTy);
|
||||
}
|
||||
// If there's a constant offset added to the integer value before
|
||||
// it is casted back to a pointer, see if the expression can be
|
||||
// converted into a GEP.
|
||||
if (CE->getOpcode() == Instruction::Add)
|
||||
if (ConstantInt *L = dyn_cast<ConstantInt>(CE->getOperand(0)))
|
||||
if (ConstantExpr *R = dyn_cast<ConstantExpr>(CE->getOperand(1)))
|
||||
if (R->getOpcode() == Instruction::PtrToInt)
|
||||
if (GlobalVariable *GV =
|
||||
dyn_cast<GlobalVariable>(R->getOperand(0))) {
|
||||
const PointerType *GVTy = cast<PointerType>(GV->getType());
|
||||
if (const ArrayType *AT =
|
||||
dyn_cast<ArrayType>(GVTy->getElementType())) {
|
||||
const Type *ElTy = AT->getElementType();
|
||||
uint64_t PaddedSize = TD->getTypePaddedSize(ElTy);
|
||||
APInt PSA(L->getValue().getBitWidth(), PaddedSize);
|
||||
if (ElTy == cast<PointerType>(DestTy)->getElementType() &&
|
||||
L->getValue().urem(PSA) == 0) {
|
||||
APInt ElemIdx = L->getValue().udiv(PSA);
|
||||
if (ElemIdx.ult(APInt(ElemIdx.getBitWidth(),
|
||||
AT->getNumElements()))) {
|
||||
Constant *Index[] = {
|
||||
Constant::getNullValue(CE->getType()),
|
||||
ConstantInt::get(ElemIdx)
|
||||
};
|
||||
return ConstantExpr::getGetElementPtr(GV, &Index[0], 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ConstantExpr::getCast(Opcode, Ops[0], DestTy);
|
||||
|
18
test/Transforms/InstCombine/constant-fold-ptr-casts.ll
Normal file
18
test/Transforms/InstCombine/constant-fold-ptr-casts.ll
Normal file
@ -0,0 +1,18 @@
|
||||
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret i32 2143034560}
|
||||
|
||||
; Instcombine should be able to completely fold this code.
|
||||
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||
target triple = "i686-apple-darwin8"
|
||||
|
||||
@bar = constant [3 x i64] [i64 9220983451228067448, i64 9220983451228067449, i64 9220983450959631991], align 8
|
||||
|
||||
define i32 @foo() nounwind {
|
||||
entry:
|
||||
%tmp87.2 = load i64* inttoptr (i32 add (i32 16, i32 ptrtoint ([3 x i64]* @bar to i32)) to i64*), align 8
|
||||
%t0 = bitcast i64 %tmp87.2 to double
|
||||
%tmp9192.2 = fptrunc double %t0 to float
|
||||
%t1 = bitcast float %tmp9192.2 to i32
|
||||
ret i32 %t1
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user