diff options
author | Dan Gohman <gohman@apple.com> | 2009-11-23 16:22:21 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-11-23 16:22:21 +0000 |
commit | 01b97dd01eec1197d79fceb7229f5ec233994de3 (patch) | |
tree | 88196a1f71041f2236951d786a30477f28c9262c | |
parent | 8f3817f505029e97d28c54548069d5bbaa9d5527 (diff) |
Make ConstantFoldConstantExpression recursively visit the entire
ConstantExpr, not just the top-level operator. This allows it to
fold many more constants.
Also, make GlobalOpt call ConstantFoldConstantExpression on
GlobalVariable initializers.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89659 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Analysis/ConstantFolding.cpp | 13 | ||||
-rw-r--r-- | lib/Transforms/IPO/GlobalOpt.cpp | 9 | ||||
-rw-r--r-- | test/Transforms/GlobalOpt/constantfold-initializers.ll | 8 | ||||
-rw-r--r-- | test/Transforms/InstCombine/cast.ll | 4 | ||||
-rw-r--r-- | test/Transforms/InstCombine/shufflevec-constant.ll | 2 |
5 files changed, 31 insertions, 5 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 1cdadbfcea..8d60907f8c 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -671,8 +671,13 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) { Constant *llvm::ConstantFoldConstantExpression(ConstantExpr *CE, const TargetData *TD) { SmallVector<Constant*, 8> Ops; - for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i) - Ops.push_back(cast<Constant>(*i)); + for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i) { + Constant *NewC = cast<Constant>(*i); + // Recursively fold the ConstantExpr's operands. + if (ConstantExpr *NewCE = dyn_cast<ConstantExpr>(NewC)) + NewC = ConstantFoldConstantExpression(NewCE, TD); + Ops.push_back(NewC); + } if (CE->isCompare()) return ConstantFoldCompareInstOperands(CE->getPredicate(), Ops[0], Ops[1], @@ -687,6 +692,10 @@ Constant *llvm::ConstantFoldConstantExpression(ConstantExpr *CE, /// attempting to fold instructions like loads and stores, which have no /// constant expression form. /// +/// TODO: This function neither utilizes nor preserves nsw/nuw/inbounds/etc +/// information, due to only being passed an opcode and operands. Constant +/// folding using this function strips this information. +/// Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy, Constant* const* Ops, unsigned NumOps, const TargetData *TD) { diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 442f2fb655..4635d0e61c 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -1898,6 +1898,15 @@ bool GlobalOpt::OptimizeGlobalVars(Module &M) { // Global variables without names cannot be referenced outside this module. if (!GV->hasName() && !GV->isDeclaration()) GV->setLinkage(GlobalValue::InternalLinkage); + // Simplify the initializer. + if (GV->hasInitializer()) + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(GV->getInitializer())) { + TargetData *TD = getAnalysisIfAvailable<TargetData>(); + Constant *New = ConstantFoldConstantExpression(CE, TD); + if (New && New != CE) + GV->setInitializer(New); + } + // Do more involved optimizations if the global is internal. if (!GV->isConstant() && GV->hasLocalLinkage() && GV->hasInitializer()) Changed |= ProcessInternalGlobal(GV, GVI); diff --git a/test/Transforms/GlobalOpt/constantfold-initializers.ll b/test/Transforms/GlobalOpt/constantfold-initializers.ll new file mode 100644 index 0000000000..834bd0012e --- /dev/null +++ b/test/Transforms/GlobalOpt/constantfold-initializers.ll @@ -0,0 +1,8 @@ +; RUN: opt < %s -S -globalopt | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" + +@.str91250 = global [3 x i8] zeroinitializer + +; CHECK: @A = global i1 false +@A = global i1 icmp ne (i64 sub nsw (i64 ptrtoint (i8* getelementptr inbounds ([3 x i8]* @.str91250, i64 0, i64 1) to i64), i64 ptrtoint ([3 x i8]* @.str91250 to i64)), i64 1) diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll index e7695b74b7..5f75cd0a89 100644 --- a/test/Transforms/InstCombine/cast.ll +++ b/test/Transforms/InstCombine/cast.ll @@ -103,7 +103,7 @@ define i32* @test12() { %p = malloc [4 x i8] ; <[4 x i8]*> [#uses=1] %c = bitcast [4 x i8]* %p to i32* ; <i32*> [#uses=1] ret i32* %c -; CHECK: %malloccall = tail call i8* @malloc(i32 ptrtoint ([4 x i8]* getelementptr ([4 x i8]* null, i32 1) to i32)) +; CHECK: %malloccall = tail call i8* @malloc(i32 4) ; CHECK: ret i32* %c } @@ -275,7 +275,7 @@ define void @test32(double** %tmp) { %tmp8.upgrd.1 = bitcast [16 x i8]* %tmp8 to double* ; <double*> [#uses=1] store double* %tmp8.upgrd.1, double** %tmp ret void -; CHECK: %malloccall = tail call i8* @malloc(i32 ptrtoint ([16 x i8]* getelementptr ([16 x i8]* null, i32 1) to i32)) +; CHECK: %malloccall = tail call i8* @malloc(i32 16) ; CHECK: %tmp8.upgrd.1 = bitcast i8* %malloccall to double* ; CHECK: store double* %tmp8.upgrd.1, double** %tmp ; CHECK: ret void diff --git a/test/Transforms/InstCombine/shufflevec-constant.ll b/test/Transforms/InstCombine/shufflevec-constant.ll index 2c667903b1..29ae5a7982 100644 --- a/test/Transforms/InstCombine/shufflevec-constant.ll +++ b/test/Transforms/InstCombine/shufflevec-constant.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -instcombine -S | grep "2 x float" +; RUN: opt < %s -instcombine -S | grep {ret <4 x float> <float 0.000000e+00, float 0.000000e+00, float 0x7FF0000000000000, float 0x7FF0000000000000>} 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 = "i386-apple-darwin9" |