forked from OSchip/llvm-project
Add support for detecting undefined shift behavior. WIP.
llvm-svn: 91341
This commit is contained in:
parent
bee6f16fed
commit
ba6a0c40c4
|
@ -1526,6 +1526,16 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
|
|||
if (Ops.LHS->getType() != RHS->getType())
|
||||
RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
|
||||
|
||||
if (CGF.CatchUndefined
|
||||
&& isa<llvm::IntegerType>(Ops.LHS->getType())) {
|
||||
unsigned Width = cast<llvm::IntegerType>(Ops.LHS->getType())->getBitWidth();
|
||||
llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
|
||||
CGF.Builder.CreateCondBr(Builder.CreateICmpULT(RHS,
|
||||
llvm::ConstantInt::get(RHS->getType(), Width)),
|
||||
Cont, CGF.getAbortBB());
|
||||
CGF.EmitBlock(Cont);
|
||||
}
|
||||
|
||||
return Builder.CreateShl(Ops.LHS, RHS, "shl");
|
||||
}
|
||||
|
||||
|
@ -1536,6 +1546,16 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
|
|||
if (Ops.LHS->getType() != RHS->getType())
|
||||
RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
|
||||
|
||||
if (CGF.CatchUndefined
|
||||
&& isa<llvm::IntegerType>(Ops.LHS->getType())) {
|
||||
unsigned Width = cast<llvm::IntegerType>(Ops.LHS->getType())->getBitWidth();
|
||||
llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
|
||||
CGF.Builder.CreateCondBr(Builder.CreateICmpULT(RHS,
|
||||
llvm::ConstantInt::get(RHS->getType(), Width)),
|
||||
Cont, CGF.getAbortBB());
|
||||
CGF.EmitBlock(Cont);
|
||||
}
|
||||
|
||||
if (Ops.Ty->isUnsignedIntegerType())
|
||||
return Builder.CreateLShr(Ops.LHS, RHS, "shr");
|
||||
return Builder.CreateAShr(Ops.LHS, RHS, "shr");
|
||||
|
|
|
@ -31,8 +31,8 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
|
|||
DebugInfo(0), IndirectBranch(0),
|
||||
SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0),
|
||||
CXXThisDecl(0), CXXVTTDecl(0),
|
||||
ConditionalBranchLevel(0), TerminateHandler(0),
|
||||
UniqueAggrDestructorCount(0), AbortBB(0) {
|
||||
ConditionalBranchLevel(0), TerminateHandler(0), AbortBB(0),
|
||||
UniqueAggrDestructorCount(0) {
|
||||
LLVMIntTy = ConvertType(getContext().IntTy);
|
||||
LLVMPointerWidth = Target.getPointerWidth(0);
|
||||
Exceptions = getContext().getLangOptions().Exceptions;
|
||||
|
|
|
@ -425,6 +425,7 @@ private:
|
|||
unsigned getByRefValueLLVMField(const ValueDecl *VD) const;
|
||||
|
||||
llvm::BasicBlock *TerminateHandler;
|
||||
llvm::BasicBlock *AbortBB;
|
||||
|
||||
int UniqueAggrDestructorCount;
|
||||
public:
|
||||
|
@ -1194,6 +1195,10 @@ public:
|
|||
/// try to simplify the codegen of the conditional based on the branch.
|
||||
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock,
|
||||
llvm::BasicBlock *FalseBlock);
|
||||
|
||||
/// getAbortBB - Create a basic block that will call abort. We'll generate
|
||||
/// a branch around the created basic block as necessary.
|
||||
llvm::BasicBlock* getAbortBB();
|
||||
private:
|
||||
|
||||
void EmitReturnOfRValue(RValue RV, QualType Ty);
|
||||
|
@ -1267,11 +1272,6 @@ private:
|
|||
ArgType));
|
||||
}
|
||||
}
|
||||
|
||||
llvm::BasicBlock *AbortBB;
|
||||
/// getAbortBB - Create a basic block that will call abort. We'll generate
|
||||
/// a branch around the created basic block as necessary.
|
||||
llvm::BasicBlock* getAbortBB();
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue