forked from OSchip/llvm-project
[InstSimplify] Cast folding can be made more generic
Use isEliminableCastPair to determine if a pair of casts are foldable. llvm-svn: 276777
This commit is contained in:
parent
2f2bd8caf4
commit
6774d612d4
|
@ -238,15 +238,9 @@ namespace llvm {
|
||||||
AssumptionCache *AC = nullptr,
|
AssumptionCache *AC = nullptr,
|
||||||
const Instruction *CxtI = nullptr);
|
const Instruction *CxtI = nullptr);
|
||||||
|
|
||||||
/// Given operands for an TruncInst, fold the result or return null.
|
/// Given operands for a CastInst, fold the result or return null.
|
||||||
Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout &DL,
|
Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
|
||||||
const TargetLibraryInfo *TLI = nullptr,
|
const DataLayout &DL,
|
||||||
const DominatorTree *DT = nullptr,
|
|
||||||
AssumptionCache *AC = nullptr,
|
|
||||||
const Instruction *CxtI = nullptr);
|
|
||||||
|
|
||||||
/// Given operands for an BitCastInst, fold the result or return null.
|
|
||||||
Value *SimplifyBitCastInst(Value *Op, Type *Ty, const DataLayout &DL,
|
|
||||||
const TargetLibraryInfo *TLI = nullptr,
|
const TargetLibraryInfo *TLI = nullptr,
|
||||||
const DominatorTree *DT = nullptr,
|
const DominatorTree *DT = nullptr,
|
||||||
AssumptionCache *AC = nullptr,
|
AssumptionCache *AC = nullptr,
|
||||||
|
|
|
@ -69,8 +69,8 @@ static Value *SimplifyCmpInst(unsigned, Value *, Value *, const Query &,
|
||||||
unsigned);
|
unsigned);
|
||||||
static Value *SimplifyOrInst(Value *, Value *, const Query &, unsigned);
|
static Value *SimplifyOrInst(Value *, Value *, const Query &, unsigned);
|
||||||
static Value *SimplifyXorInst(Value *, Value *, const Query &, unsigned);
|
static Value *SimplifyXorInst(Value *, Value *, const Query &, unsigned);
|
||||||
static Value *SimplifyTruncInst(Value *, Type *, const Query &, unsigned);
|
static Value *SimplifyCastInst(unsigned, Value *, Type *,
|
||||||
static Value *SimplifyBitCastInst(Value *, Type *, const Query &, unsigned);
|
const Query &, unsigned);
|
||||||
|
|
||||||
/// For a boolean type, or a vector of boolean type, return false, or
|
/// For a boolean type, or a vector of boolean type, return false, or
|
||||||
/// a vector with every element false, as appropriate for the type.
|
/// a vector with every element false, as appropriate for the type.
|
||||||
|
@ -748,7 +748,8 @@ static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||||
// See if "V === X - Y" simplifies.
|
// See if "V === X - Y" simplifies.
|
||||||
if (Value *V = SimplifyBinOp(Instruction::Sub, X, Y, Q, MaxRecurse-1))
|
if (Value *V = SimplifyBinOp(Instruction::Sub, X, Y, Q, MaxRecurse-1))
|
||||||
// It does! Now see if "trunc V" simplifies.
|
// It does! Now see if "trunc V" simplifies.
|
||||||
if (Value *W = SimplifyTruncInst(V, Op0->getType(), Q, MaxRecurse-1))
|
if (Value *W = SimplifyCastInst(Instruction::Trunc, V, Op0->getType(),
|
||||||
|
Q, MaxRecurse - 1))
|
||||||
// It does, return the simplified "trunc V".
|
// It does, return the simplified "trunc V".
|
||||||
return W;
|
return W;
|
||||||
|
|
||||||
|
@ -3790,48 +3791,46 @@ static Value *SimplifyPHINode(PHINode *PN, const Query &Q) {
|
||||||
return CommonValue;
|
return CommonValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Value *SimplifyTruncInst(Value *Op, Type *Ty, const Query &Q, unsigned) {
|
static Value *SimplifyCastInst(unsigned CastOpc, Value *Op,
|
||||||
|
Type *Ty, const Query &Q, unsigned MaxRecurse) {
|
||||||
if (auto *C = dyn_cast<Constant>(Op))
|
if (auto *C = dyn_cast<Constant>(Op))
|
||||||
return ConstantFoldCastOperand(Instruction::Trunc, C, Ty, Q.DL);
|
return ConstantFoldCastOperand(CastOpc, C, Ty, Q.DL);
|
||||||
|
|
||||||
// trunc([zs]ext(x)) -> x if the trunc undoes the work of the [zs]ext.
|
if (auto *CI = dyn_cast<CastInst>(Op)) {
|
||||||
if (auto *CI = dyn_cast<CastInst>(Op))
|
auto *Src = CI->getOperand(0);
|
||||||
if (isa<ZExtInst>(CI) || isa<SExtInst>(CI))
|
Type *SrcTy = Src->getType();
|
||||||
if (CI->getOperand(0)->getType() == Ty)
|
Type *MidTy = CI->getType();
|
||||||
return CI->getOperand(0);
|
Type *DstTy = Ty;
|
||||||
|
if (Src->getType() == Ty) {
|
||||||
return nullptr;
|
auto FirstOp = static_cast<Instruction::CastOps>(CI->getOpcode());
|
||||||
}
|
auto SecondOp = static_cast<Instruction::CastOps>(CastOpc);
|
||||||
|
Type *SrcIntPtrTy =
|
||||||
Value *llvm::SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout &DL,
|
SrcTy->isPtrOrPtrVectorTy() ? Q.DL.getIntPtrType(SrcTy) : nullptr;
|
||||||
const TargetLibraryInfo *TLI,
|
Type *MidIntPtrTy =
|
||||||
const DominatorTree *DT, AssumptionCache *AC,
|
MidTy->isPtrOrPtrVectorTy() ? Q.DL.getIntPtrType(MidTy) : nullptr;
|
||||||
const Instruction *CxtI) {
|
Type *DstIntPtrTy =
|
||||||
return ::SimplifyTruncInst(Op, Ty, Query(DL, TLI, DT, AC, CxtI),
|
DstTy->isPtrOrPtrVectorTy() ? Q.DL.getIntPtrType(DstTy) : nullptr;
|
||||||
RecursionLimit);
|
if (CastInst::isEliminableCastPair(FirstOp, SecondOp, SrcTy, MidTy, DstTy,
|
||||||
}
|
SrcIntPtrTy, MidIntPtrTy,
|
||||||
|
DstIntPtrTy) == Instruction::BitCast)
|
||||||
static Value *SimplifyBitCastInst(Value *Op, Type *Ty, const Query &Q, unsigned) {
|
return Src;
|
||||||
if (auto *C = dyn_cast<Constant>(Op))
|
}
|
||||||
return ConstantFoldCastOperand(Instruction::BitCast, C, Ty, Q.DL);
|
}
|
||||||
|
|
||||||
// bitcast x -> x
|
// bitcast x -> x
|
||||||
|
if (CastOpc == Instruction::BitCast)
|
||||||
if (Op->getType() == Ty)
|
if (Op->getType() == Ty)
|
||||||
return Op;
|
return Op;
|
||||||
|
|
||||||
// bitcast(bitcast x) -> x
|
|
||||||
if (auto *BC = dyn_cast<BitCastInst>(Op))
|
|
||||||
if (BC->getOperand(0)->getType() == Ty)
|
|
||||||
return BC->getOperand(0);
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *llvm::SimplifyBitCastInst(Value *Op, Type *Ty, const DataLayout &DL,
|
Value *llvm::SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
|
||||||
|
const DataLayout &DL,
|
||||||
const TargetLibraryInfo *TLI,
|
const TargetLibraryInfo *TLI,
|
||||||
const DominatorTree *DT, AssumptionCache *AC,
|
const DominatorTree *DT, AssumptionCache *AC,
|
||||||
const Instruction *CxtI) {
|
const Instruction *CxtI) {
|
||||||
return ::SimplifyBitCastInst(Op, Ty, Query(DL, TLI, DT, AC, CxtI),
|
return ::SimplifyCastInst(CastOpc, Op, Ty, Query(DL, TLI, DT, AC, CxtI),
|
||||||
RecursionLimit);
|
RecursionLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4301,13 +4300,11 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL,
|
||||||
TLI, DT, AC, I);
|
TLI, DT, AC, I);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Instruction::Trunc:
|
#define HANDLE_CAST_INST(num, opc, clas) case Instruction::opc:
|
||||||
Result =
|
#include "llvm/IR/Instruction.def"
|
||||||
SimplifyTruncInst(I->getOperand(0), I->getType(), DL, TLI, DT, AC, I);
|
#undef HANDLE_CAST_INST
|
||||||
break;
|
Result = SimplifyCastInst(I->getOpcode(), I->getOperand(0), I->getType(),
|
||||||
case Instruction::BitCast:
|
DL, TLI, DT, AC, I);
|
||||||
Result =
|
|
||||||
SimplifyBitCastInst(I->getOperand(0), I->getType(), DL, TLI, DT, AC, I);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,7 @@ define <2 x i32> @test1() {
|
||||||
; CHECK: %v3 = inttoptr <2 x i32> %v2 to <2 x i8*>
|
; CHECK: %v3 = inttoptr <2 x i32> %v2 to <2 x i8*>
|
||||||
; CHECK: %v4 = bitcast <2 x i32>* %v1 to <2 x i8*>*
|
; CHECK: %v4 = bitcast <2 x i32>* %v1 to <2 x i8*>*
|
||||||
; CHECK: store <2 x i8*> %v3, <2 x i8*>* %v4
|
; CHECK: store <2 x i8*> %v3, <2 x i8*>* %v4
|
||||||
; CHECK: %1 = ptrtoint <2 x i8*> %v3 to <2 x i32>
|
; CHECK: ret <2 x i32> %v2
|
||||||
; CHECK: ret <2 x i32> %1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @anything(<2 x i32>*)
|
declare void @anything(<2 x i32>*)
|
||||||
|
|
Loading…
Reference in New Issue