llvm.org GIT mirror llvm / abc4fc5
[GVN] Recommit the patch "Add phi-translate support in scalarpre". The recommit fixes two bugs: The first one is to use CurrentBlock instead of PREInstr's Parent as param of performScalarPREInsertion because the Parent of a clone instruction may be uninitialized. The second one is stop PRE when CurrentBlock to its predecessor is a backedge and an operand of CurInst is defined inside of CurrentBlock. The same value defined inside of loop in last iteration can not be regarded as available. Right now scalarpre doesn't have phi-translate support, so it will miss some simple pre opportunities. Like the following testcase, current scalarpre cannot recognize the last "a * b" is fully redundent because a and b used by the last "a * b" expr are both defined by phis. long a[100], b[100], g1, g2, g3; __attribute__((pure)) long goo(); void foo(long a, long b, long c, long d) { g1 = a * b; if (__builtin_expect(g2 > 3, 0)) { a = c; b = d; g2 = a * b; } g3 = a * b; // fully redundant. } The patch adds phi-translate support in scalarpre. This is only a temporary solution before the newpre based on newgvn is available. Differential Revision: https://reviews.llvm.org/D32252 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305578 91177308-0d34-0410-b5e6-96231b3b80d8 Wei Mi 2 years ago
5 changed file(s) with 321 addition(s) and 34 deletion(s). Raw diff Collapse all Expand all
6767 class ValueTable {
6868 DenseMap valueNumbering;
6969 DenseMap expressionNumbering;
70
71 // Expressions is the vector of Expression. ExprIdx is the mapping from
72 // value number to the index of Expression in Expressions. We use it
73 // instead of a DenseMap because filling such mapping is faster than
74 // filling a DenseMap and the compile time is a little better.
75 uint32_t nextExprNumber;
76 std::vector Expressions;
77 std::vector ExprIdx;
78 // Value number to PHINode mapping. Used for phi-translate in scalarpre.
79 DenseMap NumberingPhi;
80 // Cache for phi-translate in scalarpre.
81 typedef DenseMap, uint32_t>
82 PhiTranslateMap;
83 PhiTranslateMap PhiTranslateTable;
84
7085 AliasAnalysis *AA;
7186 MemoryDependenceResults *MD;
7287 DominatorTree *DT;
7893 Value *LHS, Value *RHS);
7994 Expression createExtractvalueExpr(ExtractValueInst *EI);
8095 uint32_t lookupOrAddCall(CallInst *C);
96 uint32_t phiTranslateImpl(const BasicBlock *BB, const BasicBlock *PhiBlock,
97 uint32_t Num, GVN &Gvn);
98 std::pair assignExpNewValueNum(Expression &exp);
99 bool areAllValsInBB(uint32_t num, const BasicBlock *BB, GVN &Gvn);
81100
82101 public:
83102 ValueTable();
86105 ~ValueTable();
87106
88107 uint32_t lookupOrAdd(Value *V);
89 uint32_t lookup(Value *V) const;
108 uint32_t lookup(Value *V, bool Verify = true) const;
90109 uint32_t lookupOrAddCmp(unsigned Opcode, CmpInst::Predicate Pred,
91110 Value *LHS, Value *RHS);
111 uint32_t phiTranslate(const BasicBlock *BB, const BasicBlock *PhiBlock,
112 uint32_t Num, GVN &Gvn);
92113 bool exists(Value *V) const;
93114 void add(Value *V, uint32_t num);
94115 void clear();
129150 // to the remaining instructions in the block.
130151 SmallMapVector ReplaceWithConstMap;
131152 SmallVector InstrsToErase;
153
154 // Map the block to reversed postorder traversal number. It is used to
155 // find back edge easily.
156 DenseMap BlockRPONumber;
132157
133158 typedef SmallVector LoadDepVect;
134159 typedef SmallVector AvailValInBlkVect;
213238 bool performPRE(Function &F);
214239 bool performScalarPRE(Instruction *I);
215240 bool performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred,
216 unsigned int ValNo);
241 BasicBlock *Curr, unsigned int ValNo);
217242 Value *findLeader(const BasicBlock *BB, uint32_t num);
218243 void cleanupGlobalSets();
219244 void verifyRemoved(const Instruction *I) const;
225250 bool processFoldableCondBr(BranchInst *BI);
226251 void addDeadBlock(BasicBlock *BB);
227252 void assignValNumForDeadCode();
253 void assignBlockRPONumber(Function &F);
228254 };
229255
230256 /// Create a legacy GVN pass. This also allows parameterizing whether or not
7979 struct llvm::GVN::Expression {
8080 uint32_t opcode;
8181 Type *type;
82 bool commutative;
8283 SmallVector varargs;
8384
84 Expression(uint32_t o = ~2U) : opcode(o) {}
85 Expression(uint32_t o = ~2U) : opcode(o), commutative(false) {}
8586
8687 bool operator==(const Expression &other) const {
8788 if (opcode != other.opcode)
245246 assert(I->getNumOperands() == 2 && "Unsupported commutative instruction!");
246247 if (e.varargs[0] > e.varargs[1])
247248 std::swap(e.varargs[0], e.varargs[1]);
249 e.commutative = true;
248250 }
249251
250252 if (CmpInst *C = dyn_cast(I)) {
255257 Predicate = CmpInst::getSwappedPredicate(Predicate);
256258 }
257259 e.opcode = (C->getOpcode() << 8) | Predicate;
260 e.commutative = true;
258261 } else if (InsertValueInst *E = dyn_cast(I)) {
259262 for (InsertValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end();
260263 II != IE; ++II)
280283 Predicate = CmpInst::getSwappedPredicate(Predicate);
281284 }
282285 e.opcode = (Opcode << 8) | Predicate;
286 e.commutative = true;
283287 return e;
284288 }
285289
347351 /// add - Insert a value into the table with a specified value number.
348352 void GVN::ValueTable::add(Value *V, uint32_t num) {
349353 valueNumbering.insert(std::make_pair(V, num));
354 if (PHINode *PN = dyn_cast(V))
355 NumberingPhi[num] = PN;
350356 }
351357
352358 uint32_t GVN::ValueTable::lookupOrAddCall(CallInst *C) {
353359 if (AA->doesNotAccessMemory(C)) {
354360 Expression exp = createExpr(C);
355 uint32_t &e = expressionNumbering[exp];
356 if (!e) e = nextValueNumber++;
361 uint32_t e = assignExpNewValueNum(exp).first;
357362 valueNumbering[C] = e;
358363 return e;
359364 } else if (AA->onlyReadsMemory(C)) {
360365 Expression exp = createExpr(C);
361 uint32_t &e = expressionNumbering[exp];
362 if (!e) {
363 e = nextValueNumber++;
364 valueNumbering[C] = e;
365 return e;
366 auto ValNum = assignExpNewValueNum(exp);
367 if (ValNum.second) {
368 valueNumbering[C] = ValNum.first;
369 return ValNum.first;
366370 }
367371 if (!MD) {
368 e = nextValueNumber++;
372 uint32_t e = assignExpNewValueNum(exp).first;
369373 valueNumbering[C] = e;
370374 return e;
371375 }
521525 case Instruction::ExtractValue:
522526 exp = createExtractvalueExpr(cast(I));
523527 break;
528 case Instruction::PHI:
529 valueNumbering[V] = nextValueNumber;
530 NumberingPhi[nextValueNumber] = cast(V);
531 return nextValueNumber++;
524532 default:
525533 valueNumbering[V] = nextValueNumber;
526534 return nextValueNumber++;
527535 }
528536
529 uint32_t& e = expressionNumbering[exp];
530 if (!e) e = nextValueNumber++;
537 uint32_t e = assignExpNewValueNum(exp).first;
531538 valueNumbering[V] = e;
532539 return e;
533540 }
534541
535542 /// Returns the value number of the specified value. Fails if
536543 /// the value has not yet been numbered.
537 uint32_t GVN::ValueTable::lookup(Value *V) const {
544 uint32_t GVN::ValueTable::lookup(Value *V, bool Verify) const {
538545 DenseMap::const_iterator VI = valueNumbering.find(V);
539 assert(VI != valueNumbering.end() && "Value not numbered?");
540 return VI->second;
546 if (Verify) {
547 assert(VI != valueNumbering.end() && "Value not numbered?");
548 return VI->second;
549 }
550 return (VI != valueNumbering.end()) ? VI->second : 0;
541551 }
542552
543553 /// Returns the value number of the given comparison,
548558 CmpInst::Predicate Predicate,
549559 Value *LHS, Value *RHS) {
550560 Expression exp = createCmpExpr(Opcode, Predicate, LHS, RHS);
551 uint32_t& e = expressionNumbering[exp];
552 if (!e) e = nextValueNumber++;
553 return e;
561 return assignExpNewValueNum(exp).first;
554562 }
555563
556564 /// Remove all entries from the ValueTable.
557565 void GVN::ValueTable::clear() {
558566 valueNumbering.clear();
559567 expressionNumbering.clear();
568 NumberingPhi.clear();
569 PhiTranslateTable.clear();
560570 nextValueNumber = 1;
571 Expressions.clear();
572 ExprIdx.clear();
573 nextExprNumber = 0;
561574 }
562575
563576 /// Remove a value from the value numbering.
564577 void GVN::ValueTable::erase(Value *V) {
578 uint32_t Num = valueNumbering.lookup(V);
565579 valueNumbering.erase(V);
580 // If V is PHINode, V <--> value number is an one-to-one mapping.
581 if (isa(V))
582 NumberingPhi.erase(Num);
566583 }
567584
568585 /// verifyRemoved - Verify that the value is removed from all internal data
14501467 return false;
14511468 }
14521469
1470 /// Return a pair the first field showing the value number of \p Exp and the
1471 /// second field showing whether it is a value number newly created.
1472 std::pair
1473 GVN::ValueTable::assignExpNewValueNum(Expression &Exp) {
1474 uint32_t &e = expressionNumbering[Exp];
1475 bool CreateNewValNum = !e;
1476 if (CreateNewValNum) {
1477 Expressions.push_back(Exp);
1478 if (ExprIdx.size() < nextValueNumber + 1)
1479 ExprIdx.resize(nextValueNumber * 2);
1480 e = nextValueNumber;
1481 ExprIdx[nextValueNumber++] = nextExprNumber++;
1482 }
1483 return {e, CreateNewValNum};
1484 }
1485
1486 /// Return whether all the values related with the same \p num are
1487 /// defined in \p BB.
1488 bool GVN::ValueTable::areAllValsInBB(uint32_t Num, const BasicBlock *BB,
1489 GVN &Gvn) {
1490 LeaderTableEntry *Vals = &Gvn.LeaderTable[Num];
1491 while (Vals && Vals->BB == BB)
1492 Vals = Vals->Next;
1493 return !Vals;
1494 }
1495
1496 /// Wrap phiTranslateImpl to provide caching functionality.
1497 uint32_t GVN::ValueTable::phiTranslate(const BasicBlock *Pred,
1498 const BasicBlock *PhiBlock, uint32_t Num,
1499 GVN &Gvn) {
1500 auto FindRes = PhiTranslateTable.find({Num, Pred});
1501 if (FindRes != PhiTranslateTable.end())
1502 return FindRes->second;
1503 uint32_t NewNum = phiTranslateImpl(Pred, PhiBlock, Num, Gvn);
1504 PhiTranslateTable.insert({{Num, Pred}, NewNum});
1505 return NewNum;
1506 }
1507
1508 /// Translate value number \p Num using phis, so that it has the values of
1509 /// the phis in BB.
1510 uint32_t GVN::ValueTable::phiTranslateImpl(const BasicBlock *Pred,
1511 const BasicBlock *PhiBlock,
1512 uint32_t Num, GVN &Gvn) {
1513 if (PHINode *PN = NumberingPhi[Num]) {
1514 for (unsigned i = 0; i != PN->getNumIncomingValues(); ++i) {
1515 if (PN->getParent() == PhiBlock && PN->getIncomingBlock(i) == Pred)
1516 if (uint32_t TransVal = lookup(PN->getIncomingValue(i), false))
1517 return TransVal;
1518 }
1519 return Num;
1520 }
1521
1522 // If there is any value related with Num is defined in a BB other than
1523 // PhiBlock, it cannot depend on a phi in PhiBlock without going through
1524 // a backedge. We can do an early exit in that case to save compile time.
1525 if (!areAllValsInBB(Num, PhiBlock, Gvn))
1526 return Num;
1527
1528 if (ExprIdx[Num] == 0 || Num >= ExprIdx.size())
1529 return Num;
1530 Expression Exp = Expressions[ExprIdx[Num]];
1531
1532 for (unsigned i = 0; i < Exp.varargs.size(); i++) {
1533 // For InsertValue and ExtractValue, some varargs are index numbers
1534 // instead of value numbers. Those index numbers should not be
1535 // translated.
1536 if ((i > 1 && Exp.opcode == Instruction::InsertValue) ||
1537 (i > 0 && Exp.opcode == Instruction::ExtractValue))
1538 continue;
1539 Exp.varargs[i] = phiTranslate(Pred, PhiBlock, Exp.varargs[i], Gvn);
1540 }
1541
1542 if (Exp.commutative) {
1543 assert(Exp.varargs.size() == 2 && "Unsupported commutative expression!");
1544 if (Exp.varargs[0] > Exp.varargs[1]) {
1545 std::swap(Exp.varargs[0], Exp.varargs[1]);
1546 uint32_t Opcode = Exp.opcode >> 8;
1547 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp)
1548 Exp.opcode = (Opcode << 8) |
1549 CmpInst::getSwappedPredicate(
1550 static_cast(Exp.opcode & 255));
1551 }
1552 }
1553
1554 if (uint32_t NewNum = expressionNumbering[Exp])
1555 return NewNum;
1556 return Num;
1557 }
1558
14531559 // In order to find a leader for a given value number at a
14541560 // specific basic block, we first obtain the list of all Values for that number,
14551561 // and then scan the list to find one whose block dominates the block in
14931599 "No edge between these basic blocks!");
14941600 return Pred != nullptr;
14951601 }
1602
1603
1604 void GVN::assignBlockRPONumber(Function &F) {
1605 uint32_t NextBlockNumber = 1;
1606 ReversePostOrderTraversal RPOT(&F);
1607 for (BasicBlock *BB : RPOT)
1608 BlockRPONumber[BB] = NextBlockNumber++;
1609 }
1610
14961611
14971612 // Tries to replace instruction with const, using information from
14981613 // ReplaceWithConstMap.
18551970 // Fabricate val-num for dead-code in order to suppress assertion in
18561971 // performPRE().
18571972 assignValNumForDeadCode();
1973 assignBlockRPONumber(F);
18581974 bool PREChanged = true;
18591975 while (PREChanged) {
18601976 PREChanged = performPRE(F);
19262042
19272043 // Instantiate an expression in a predecessor that lacked it.
19282044 bool GVN::performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred,
1929 unsigned int ValNo) {
2045 BasicBlock *Curr, unsigned int ValNo) {
19302046 // Because we are going top-down through the block, all value numbers
19312047 // will be available in the predecessor by the time we need them. Any
19322048 // that weren't originally present will have been instantiated earlier
19442060 success = false;
19452061 break;
19462062 }
1947 if (Value *V = findLeader(Pred, VN.lookup(Op))) {
2063 uint32_t TValNo =
2064 VN.phiTranslate(Pred, Curr, VN.lookup(Op), *this);
2065 if (Value *V = findLeader(Pred, TValNo)) {
19482066 Instr->setOperand(i, V);
19492067 } else {
19502068 success = false;
19612079 Instr->insertBefore(Pred->getTerminator());
19622080 Instr->setName(Instr->getName() + ".pre");
19632081 Instr->setDebugLoc(Instr->getDebugLoc());
1964 VN.add(Instr, ValNo);
2082
2083 unsigned Num = VN.lookupOrAdd(Instr);
2084 VN.add(Instr, Num);
19652085
19662086 // Update the availability map to include the new instruction.
1967 addToLeaderTable(ValNo, Instr, Pred);
2087 addToLeaderTable(Num, Instr, Pred);
19682088 return true;
19692089 }
19702090
20022122
20032123 SmallVector, 8> predMap;
20042124 for (BasicBlock *P : predecessors(CurrentBlock)) {
2005 // We're not interested in PRE where the block is its
2006 // own predecessor, or in blocks with predecessors
2007 // that are not reachable.
2008 if (P == CurrentBlock) {
2125 // We're not interested in PRE where blocks with predecessors that are
2126 // not reachable.
2127 if (!DT->isReachableFromEntry(P)) {
20092128 NumWithout = 2;
20102129 break;
2011 } else if (!DT->isReachableFromEntry(P)) {
2130 }
2131 // It is not safe to do PRE when P->CurrentBlock is a loop backedge, and
2132 // when CurInst has operand defined in CurrentBlock (so it may be defined
2133 // by phi in the loop header).
2134 if (BlockRPONumber[P] >= BlockRPONumber[CurrentBlock] &&
2135 any_of(CurInst->operands(), [&](const Use &U) {
2136 if (auto *Inst = dyn_cast(U.get()))
2137 return Inst->getParent() == CurrentBlock;
2138 return false;
2139 })) {
20122140 NumWithout = 2;
20132141 break;
20142142 }
20152143
2016 Value *predV = findLeader(P, ValNo);
2144 uint32_t TValNo = VN.phiTranslate(P, CurrentBlock, ValNo, *this);
2145 Value *predV = findLeader(P, TValNo);
20172146 if (!predV) {
20182147 predMap.push_back(std::make_pair(static_cast(nullptr), P));
20192148 PREPred = P;
20532182 }
20542183 // We need to insert somewhere, so let's give it a shot
20552184 PREInstr = CurInst->clone();
2056 if (!performScalarPREInsertion(PREInstr, PREPred, ValNo)) {
2185 if (!performScalarPREInsertion(PREInstr, PREPred, CurrentBlock, ValNo)) {
20572186 // If we failed insertion, make sure we remove the instruction.
20582187 DEBUG(verifyRemoved(PREInstr));
20592188 PREInstr->deleteValue();
21672296 void GVN::cleanupGlobalSets() {
21682297 VN.clear();
21692298 LeaderTable.clear();
2299 BlockRPONumber.clear();
21702300 TableAllocator.Reset();
21712301 }
21722302
0 ; RUN: opt < %s -gvn -S | FileCheck %s
1 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2
3 @a = common global [100 x i64] zeroinitializer, align 16
4 @b = common global [100 x i64] zeroinitializer, align 16
5 @g1 = common global i64 0, align 8
6 @g2 = common global i64 0, align 8
7 @g3 = common global i64 0, align 8
8 declare i64 @goo(...) local_unnamed_addr #1
9
10 define void @test1(i64 %a, i64 %b, i64 %c, i64 %d) {
11 entry:
12 %mul = mul nsw i64 %b, %a
13 store i64 %mul, i64* @g1, align 8
14 %t0 = load i64, i64* @g2, align 8
15 %cmp = icmp sgt i64 %t0, 3
16 br i1 %cmp, label %if.then, label %if.end
17
18 if.then: ; preds = %entry
19 %mul2 = mul nsw i64 %d, %c
20 store i64 %mul2, i64* @g2, align 8
21 br label %if.end
22
23 ; Check phi-translate works and mul is removed.
24 ; CHECK-LABEL: @test1(
25 ; CHECK: if.end:
26 ; CHECK: %[[MULPHI:.*]] = phi i64 [ {{.*}}, %if.then ], [ %mul, %entry ]
27 ; CHECK-NOT: = mul
28 ; CHECK: store i64 %[[MULPHI]], i64* @g3, align 8
29 if.end: ; preds = %if.then, %entry
30 %b.addr.0 = phi i64 [ %d, %if.then ], [ %b, %entry ]
31 %a.addr.0 = phi i64 [ %c, %if.then ], [ %a, %entry ]
32 %mul3 = mul nsw i64 %a.addr.0, %b.addr.0
33 store i64 %mul3, i64* @g3, align 8
34 ret void
35 }
36
37 define void @test2(i64 %i) {
38 entry:
39 %arrayidx = getelementptr inbounds [100 x i64], [100 x i64]* @a, i64 0, i64 %i
40 %t0 = load i64, i64* %arrayidx, align 8
41 %arrayidx1 = getelementptr inbounds [100 x i64], [100 x i64]* @b, i64 0, i64 %i
42 %t1 = load i64, i64* %arrayidx1, align 8
43 %mul = mul nsw i64 %t1, %t0
44 store i64 %mul, i64* @g1, align 8
45 %cmp = icmp sgt i64 %mul, 3
46 br i1 %cmp, label %if.then, label %if.end
47
48 ; Check phi-translate works for the phi generated by loadpre. A new mul will be
49 ; inserted in if.then block.
50 ; CHECK-LABEL: @test2(
51 ; CHECK: if.then:
52 ; CHECK: %[[MUL_THEN:.*]] = mul
53 ; CHECK: br label %if.end
54 if.then: ; preds = %entry
55 %call = tail call i64 (...) @goo() #2
56 store i64 %call, i64* @g2, align 8
57 br label %if.end
58
59 ; CHECK: if.end:
60 ; CHECK: %[[MULPHI:.*]] = phi i64 [ %[[MUL_THEN]], %if.then ], [ %mul, %entry ]
61 ; CHECK-NOT: = mul
62 ; CHECK: store i64 %[[MULPHI]], i64* @g3, align 8
63 if.end: ; preds = %if.then, %entry
64 %i.addr.0 = phi i64 [ 3, %if.then ], [ %i, %entry ]
65 %arrayidx3 = getelementptr inbounds [100 x i64], [100 x i64]* @a, i64 0, i64 %i.addr.0
66 %t2 = load i64, i64* %arrayidx3, align 8
67 %arrayidx4 = getelementptr inbounds [100 x i64], [100 x i64]* @b, i64 0, i64 %i.addr.0
68 %t3 = load i64, i64* %arrayidx4, align 8
69 %mul5 = mul nsw i64 %t3, %t2
70 store i64 %mul5, i64* @g3, align 8
71 ret void
72 }
73
74 ; Check phi-translate doesn't go through backedge, which may lead to incorrect
75 ; pre transformation.
76 ; CHECK: for.end:
77 ; CHECK-NOT: %{{.*pre-phi}} = phi
78 ; CHECK: ret void
79 define void @test3(i64 %N, i64* nocapture readonly %a) {
80 entry:
81 br label %for.cond
82
83 for.cond: ; preds = %for.body, %entry
84 %i.0 = phi i64 [ 0, %entry ], [ %add, %for.body ]
85 %add = add nuw nsw i64 %i.0, 1
86 %arrayidx = getelementptr inbounds i64, i64* %a, i64 %add
87 %tmp0 = load i64, i64* %arrayidx, align 8
88 %cmp = icmp slt i64 %i.0, %N
89 br i1 %cmp, label %for.body, label %for.end
90
91 for.body: ; preds = %for.cond
92 %call = tail call i64 (...) @goo() #2
93 %add1 = sub nsw i64 0, %call
94 %tobool = icmp eq i64 %tmp0, %add1
95 br i1 %tobool, label %for.cond, label %for.end
96
97 for.end: ; preds = %for.body, %for.cond
98 %i.0.lcssa = phi i64 [ %i.0, %for.body ], [ %i.0, %for.cond ]
99 %arrayidx2 = getelementptr inbounds i64, i64* %a, i64 %i.0.lcssa
100 %tmp1 = load i64, i64* %arrayidx2, align 8
101 store i64 %tmp1, i64* @g1, align 8
102 ret void
103 }
104
105 ; It is incorrect to use the value of %andres in last loop iteration
106 ; to do pre.
107 ; CHECK-LABEL: @test4(
108 ; CHECK: for.body:
109 ; CHECK-NOT: %andres.pre-phi = phi i32
110 ; CHECK: br i1 %tobool1
111
112 define i32 @test4(i32 %cond, i32 %SectionAttrs.0231.ph, i32 *%AttrFlag) {
113 for.body.preheader:
114 %t514 = load volatile i32, i32* %AttrFlag
115 br label %for.body
116
117 for.body:
118 %t320 = phi i32 [ %t334, %bb343 ], [ %t514, %for.body.preheader ]
119 %andres = and i32 %t320, %SectionAttrs.0231.ph
120 %tobool1 = icmp eq i32 %andres, 0
121 br i1 %tobool1, label %bb343, label %critedge.loopexit
122
123 bb343:
124 %t334 = load volatile i32, i32* %AttrFlag
125 %tobool2 = icmp eq i32 %cond, 0
126 br i1 %tobool2, label %critedge.loopexit, label %for.body
127
128 critedge.loopexit:
129 unreachable
130 }
3636 %3 = load double, double* %arrayidx5, align 8
3737 ; CHECK: sw.bb2:
3838 ; CHECK-NOT: sext
39 ; CHECK-NEXT: phi double [
39 ; CHECK: phi double [
4040 ; CHECK-NOT: load
4141 %sub6 = fsub double 3.000000e+00, %3
4242 br label %return
7171 %PRE = load i32, i32* %P3
7272 ret i32 %PRE
7373 ; CHECK: block4:
74 ; CHECK-NEXT: phi i32 [
74 ; CHECK: phi i32 [
7575 ; CHECK-NOT: load
7676 ; CHECK: ret i32
7777 }
103103 %PRE = load i32, i32* %P3
104104 ret i32 %PRE
105105 ; CHECK: block4:
106 ; CHECK-NEXT: phi i32 [
106 ; CHECK: phi i32 [
107107 ; CHECK-NOT: load
108108 ; CHECK: ret i32
109109 }
262262 %PRE = load i32, i32* %P3
263263 ret i32 %PRE
264264 ; CHECK: block4:
265 ; CHECK-NEXT: phi i32 [
265 ; CHECK: phi i32 [
266266 ; CHECK-NOT: load
267267 ; CHECK: ret i32
268268 }