llvm.org GIT mirror llvm / 47c282c
NewGVN: Fix PR 33461, caused by slightly overzealous verification. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305657 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Berlin 2 years ago
2 changed file(s) with 66 addition(s) and 18 deletion(s). Raw diff Collapse all Expand all
12431243 // only do this for simple stores, we should expand to cover memcpys, etc.
12441244 const auto *LastStore = createStoreExpression(SI, StoreRHS);
12451245 const auto *LastCC = ExpressionToClass.lookup(LastStore);
1246 // Basically, check if the congruence class the store is in is defined by a
1247 // store that isn't us, and has the same value. MemorySSA takes care of
1248 // ensuring the store has the same memory state as us already.
1249 // The RepStoredValue gets nulled if all the stores disappear in a class, so
1250 // we don't need to check if the class contains a store besides us.
1251 if (LastCC &&
1252 LastCC->getStoredValue() == lookupOperandLeader(SI->getValueOperand()))
1246 // We really want to check whether the expression we matched was a store. No
1247 // easy way to do that. However, we can check that the class we found has a
1248 // store, which, assuming the value numbering state is not corrupt, is
1249 // sufficient, because we must also be equivalent to that store's expression
1250 // for it to be in the same class as the load.
1251 if (LastCC && LastCC->getStoredValue() == LastStore->getStoredValue())
12531252 return LastStore;
1254 deleteExpression(LastStore);
12551253 // Also check if our value operand is defined by a load of the same memory
12561254 // location, and the memory state is the same as it was then (otherwise, it
12571255 // could have been overwritten later. See test32 in
12581256 // transforms/DeadStoreElimination/simple.ll).
1259 if (auto *LI =
1260 dyn_cast(lookupOperandLeader(SI->getValueOperand()))) {
1257 if (auto *LI = dyn_cast(LastStore->getStoredValue()))
12611258 if ((lookupOperandLeader(LI->getPointerOperand()) ==
1262 lookupOperandLeader(SI->getPointerOperand())) &&
1259 LastStore->getOperand(0)) &&
12631260 (lookupMemoryLeader(getMemoryAccess(LI)->getDefiningAccess()) ==
12641261 StoreRHS))
1265 return createStoreExpression(SI, StoreRHS);
1266 }
1262 return LastStore;
1263 deleteExpression(LastStore);
12671264 }
12681265
12691266 // If the store is not equivalent to anything, value number it as a store that
30133010 // a no-longer valid StoreExpression.
30143011 void NewGVN::verifyStoreExpressions() const {
30153012 #ifndef NDEBUG
3016 DenseSet> StoreExpressionSet;
3013 // This is the only use of this, and it's not worth defining a complicated
3014 // densemapinfo hash/equality function for it.
3015 std::set<
3016 std::pair
3017 std::tuple>>
3018 StoreExpressionSet;
30173019 for (const auto &KV : ExpressionToClass) {
30183020 if (auto *SE = dyn_cast(KV.first)) {
30193021 // Make sure a version that will conflict with loads is not already there
3020 auto Res =
3021 StoreExpressionSet.insert({SE->getOperand(0), SE->getMemoryLeader()});
3022 assert(Res.second &&
3023 "Stored expression conflict exists in expression table");
3022 auto Res = StoreExpressionSet.insert(
3023 {SE->getOperand(0), std::make_tuple(SE->getMemoryLeader(), KV.second,
3024 SE->getStoredValue())});
3025 bool Okay = Res.second;
3026 // It's okay to have the same expression already in there if it is
3027 // identical in nature.
3028 // This can happen when the leader of the stored value changes over time.
3029 if (!Okay) {
3030 Okay = Okay && std::get<1>(Res.first->second) == KV.second;
3031 Okay = Okay &&
3032 lookupOperandLeader(std::get<2>(Res.first->second)) ==
3033 lookupOperandLeader(SE->getStoredValue());
3034 }
3035 assert(Okay && "Stored expression conflict exists in expression table");
30243036 auto *ValueExpr = ValueToExpression.lookup(SE->getStoreInst());
30253037 assert(ValueExpr && ValueExpr->equals(*SE) &&
30263038 "StoreExpression in ExpressionToClass is not latest "
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ;; Ensure the store verifier is not overzealous
2 ; RUN: opt -newgvn -S %s | FileCheck %s
3 @b = external global i16, align 2
4
5 define void @patatino() {
6 ; CHECK-LABEL: @patatino(
7 ; CHECK-NEXT: entry:
8 ; CHECK-NEXT: br i1 false, label [[FOR_COND1:%.*]], label [[FOR_INC:%.*]]
9 ; CHECK: for.cond1:
10 ; CHECK-NEXT: [[TMP0:%.*]] = phi i16 [ [[INC:%.*]], [[FOR_INC]] ], [ undef, [[ENTRY:%.*]] ]
11 ; CHECK-NEXT: store i16 [[TMP0]], i16* @b, align 2
12 ; CHECK-NEXT: br label [[FOR_INC]]
13 ; CHECK: for.inc:
14 ; CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @b, align 2
15 ; CHECK-NEXT: [[INC]] = add i16 [[TMP1]], 1
16 ; CHECK-NEXT: store i16 [[INC]], i16* @b, align 2
17 ; CHECK-NEXT: br label [[FOR_COND1]]
18 ;
19 entry:
20 br i1 false, label %for.cond1, label %for.inc
21
22 for.cond1:
23 %e.0 = phi i16* [ %e.1, %for.inc ], [ null, %entry ]
24 %0 = load i16, i16* %e.0, align 2
25 %add = add i16 %0, 0
26 store i16 %add, i16* %e.0, align 2
27 br label %for.inc
28
29 for.inc:
30 %e.1 = phi i16* [ %e.0, %for.cond1 ], [ @b, %entry ]
31 %1 = load i16, i16* @b, align 2
32 %inc = add i16 %1, 1
33 store i16 %inc, i16* @b, align 2
34 br label %for.cond1
35 }