diff options
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Scalar/GVN.cpp | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index 292a97e392a..9189f41c19c 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -915,11 +915,28 @@ bool GVN::processNonLocalLoad(LoadInst* L, } if (StoreInst* S = dyn_cast<StoreInst>(DepInfo.getInst())) { - if (S->getPointerOperand() != L->getPointerOperand()) + // Reject loads and stores that are to the same address but are of + // different types. + // NOTE: 403.gcc does have this case (e.g. in readonly_fields_p) because + // of bitfield access, it would be interesting to optimize for it at some + // point. + if (S->getOperand(0)->getType() != L->getType()) + return false; + + if (S->getPointerOperand() != L->getPointerOperand() && + VN.getAliasAnalysis()->alias(S->getPointerOperand(), 1, + L->getPointerOperand(), 1) + != AliasAnalysis::MustAlias) return false; repl[DepBB] = S->getOperand(0); } else if (LoadInst* LD = dyn_cast<LoadInst>(DepInfo.getInst())) { - if (LD->getPointerOperand() != L->getPointerOperand()) + if (LD->getType() != L->getType()) + return false; + + if (LD->getPointerOperand() != L->getPointerOperand() && + VN.getAliasAnalysis()->alias(LD->getPointerOperand(), 1, + L->getPointerOperand(), 1) + != AliasAnalysis::MustAlias) return false; repl[DepBB] = LD; } else { |