Add support for detecting undefined shift behavior. WIP.

llvm-svn: 91341
This commit is contained in:
Mike Stump 2009-12-14 21:58:14 +00:00
parent bee6f16fed
commit ba6a0c40c4
3 changed files with 27 additions and 7 deletions

View File

@ -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");

View File

@ -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;

View File

@ -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();
};