diff options
author | Nikita Popov <npopov@redhat.com> | 2022-01-05 12:17:22 +0100 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2022-01-05 12:30:46 +0100 |
commit | 99c6b12b924f375a80540de721a2bc438ed3cf49 (patch) | |
tree | 3d9f4f58eb13d0f101b5411367f94bcd97ddb82c /llvm/lib/Analysis/ConstantFolding.cpp | |
parent | 00686ab4afd967fb3c10127a48096d72e4f218b5 (diff) | |
download | llvm-99c6b12b924f375a80540de721a2bc438ed3cf49.zip llvm-99c6b12b924f375a80540de721a2bc438ed3cf49.tar.gz llvm-99c6b12b924f375a80540de721a2bc438ed3cf49.tar.bz2 |
[ConstantFolding] Unify handling of load from uniform value
There are a number of places that specially handle loads from a
uniform value where all the bits are the same (zero, one, undef,
poison), because we a) don't care about the load offset in that
case b) it bypasses casts that might not be legal generally but
do work with uniform values.
We had multiple implementations of this, with a different set of
supported values each time. This replaces two usages with a more
complete helper. Other usages will be replaced separately, because
they have larger impact.
This is part of D115924.
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rw-r--r-- | llvm/lib/Analysis/ConstantFolding.cpp | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 7f7c9a5..e475f5e 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -704,15 +704,13 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, Offset, DL)) return Result; - // If this load comes from anywhere in a constant global, and if the global - // is all undef or zero, we know what it loads. + // If this load comes from anywhere in a uniform constant global, the value + // is always the same, regardless of the loaded offset. if (auto *GV = dyn_cast<GlobalVariable>(getUnderlyingObject(C))) { if (GV->isConstant() && GV->hasDefinitiveInitializer()) { - if (GV->getInitializer()->isNullValue() && !Ty->isX86_MMXTy() && - !Ty->isX86_AMXTy()) - return Constant::getNullValue(Ty); - if (isa<UndefValue>(GV->getInitializer())) - return UndefValue::get(Ty); + if (Constant *Res = + ConstantFoldLoadFromUniformValue(GV->getInitializer(), Ty)) + return Res; } } @@ -725,6 +723,19 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, return ConstantFoldLoadFromConstPtr(C, Ty, Offset, DL); } +Constant *llvm::ConstantFoldLoadFromUniformValue(Constant *C, Type *Ty) { + if (isa<PoisonValue>(C)) + return PoisonValue::get(Ty); + if (isa<UndefValue>(C)) + return UndefValue::get(Ty); + if (C->isNullValue() && !Ty->isX86_MMXTy() && !Ty->isX86_AMXTy()) + return Constant::getNullValue(Ty); + if (C->isAllOnesValue() && + (Ty->isIntOrIntVectorTy() || Ty->isFPOrFPVectorTy())) + return Constant::getAllOnesValue(Ty); + return nullptr; +} + namespace { /// One of Op0/Op1 is a constant expression. |