When building casts, constant fold with ConstantFoldInstruction instead
of ConstantExpr::getCast. This allows target-data driven constant folding
to happen. In the testcase from PR1602, for example, this results in:
%tmp26 = sub i32 %tmp232425, 1
instead of:
%tmp26 = sub i32 %tmp232425, ptrtoint (i32 (...)** inttoptr (i64 1 to i32 (...)**) to i32)
llvm-svn: 41071
diff --git a/llvm-gcc-4.2/gcc/llvm-convert.cpp b/llvm-gcc-4.2/gcc/llvm-convert.cpp
index 459d54d..ca2fca5 100644
--- a/llvm-gcc-4.2/gcc/llvm-convert.cpp
+++ b/llvm-gcc-4.2/gcc/llvm-convert.cpp
@@ -34,6 +34,7 @@
#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
+#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
@@ -1045,16 +1046,26 @@
if (V->getType() == Ty)
return V;
+ // If this is a simple constant operand, fold it now. If it is a constant
+ // expr operand, fold it below.
if (Constant *C = dyn_cast<Constant>(V))
- return ConstantExpr::getCast(Instruction::CastOps(opcode), C, Ty);
+ if (!isa<ConstantExpr>(C))
+ return ConstantExpr::getCast(Instruction::CastOps(opcode), C, Ty);
// Handle 'trunc (zext i1 X to T2) to i1' as X, because this occurs all over
// the place.
if (ZExtInst *CI = dyn_cast<ZExtInst>(V))
if (Ty == Type::Int1Ty && CI->getOperand(0)->getType() == Type::Int1Ty)
return CI->getOperand(0);
- return Builder.CreateCast(Instruction::CastOps(opcode), V, Ty,
- V->getName().c_str());
+ Value *Result = Builder.CreateCast(Instruction::CastOps(opcode), V, Ty,
+ V->getNameStart());
+
+ // If this is a constantexpr, fold the instruction with
+ // ConstantFoldInstruction to allow TargetData-driven folding to occur.
+ if (isa<ConstantExpr>(V))
+ Result = ConstantFoldInstruction(cast<Instruction>(Result), &TD);
+
+ return Result;
}
/// CastToAnyType - Cast the specified value to the specified type making no