llvm.org GIT mirror llvm / adf1668
[ARM64] PR19792: Fix cycle in DAG after performPostLD1Combine Povray and dealII currently assert with "Overran sorted position" in AssignTopologicalOrder. The problem is that performPostLD1Combine can introduce cycles. Consider: (insert_vector_elt (INSERT_SUBREG undef, (load (add %vreg0, Constant<8>), undef), <= A TargetConstant<2>), (load %vreg0, undef), <= B Constant<1>) This is turned into a LD1LANEpost node. However the address in A is not a valid user of the post-incremented address of B in LD1LANEpost. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209242 91177308-0d34-0410-b5e6-96231b3b80d8 Adam Nemet 6 years ago
2 changed file(s) with 46 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
72977297 }
72987298
72997299 SDValue Addr = LD->getOperand(1);
7300 SDValue Vector = N->getOperand(0);
73007301 // Search for a use of the address operand that is an increment.
73017302 for (SDNode::use_iterator UI = Addr.getNode()->use_begin(), UE =
73027303 Addr.getNode()->use_end(); UI != UE; ++UI) {
73087309 // Check that the add is independent of the load. Otherwise, folding it
73097310 // would create a cycle.
73107311 if (User->isPredecessorOf(LD) || LD->isPredecessorOf(User))
7312 continue;
7313 // Also check that add is not used in the vector operand. This would also
7314 // create a cycle.
7315 if (User->isPredecessorOf(Vector.getNode()))
73117316 continue;
73127317
73137318 // If the increment is a constant, it must match the memory ref size.
73237328 SmallVector Ops;
73247329 Ops.push_back(LD->getOperand(0)); // Chain
73257330 if (IsLaneOp) {
7326 Ops.push_back(N->getOperand(0)); // The vector to be inserted
7331 Ops.push_back(Vector); // The vector to be inserted
73277332 Ops.push_back(N->getOperand(2)); // The lane to be inserted in the vector
73287333 }
73297334 Ops.push_back(Addr);
0 ; RUN: llc %s
1
2 ; This used to assert with "Overran sorted position" in AssignTopologicalOrder
3 ; due to a cycle created in performPostLD1Combine.
4
5 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
6 target triple = "arm64-apple-ios7.0.0"
7
8 ; Function Attrs: nounwind ssp
9 define void @f(double* %P1) #0 {
10 entry:
11 %arrayidx4 = getelementptr inbounds double* %P1, i64 1
12 %0 = load double* %arrayidx4, align 8, !tbaa !1
13 %1 = load double* %P1, align 8, !tbaa !1
14 %2 = insertelement <2 x double> undef, double %0, i32 0
15 %3 = insertelement <2 x double> %2, double %1, i32 1
16 %4 = fsub <2 x double> zeroinitializer, %3
17 %5 = fmul <2 x double> undef, %4
18 %6 = extractelement <2 x double> %5, i32 0
19 %cmp168 = fcmp olt double %6, undef
20 br i1 %cmp168, label %if.then172, label %return
21
22 if.then172: ; preds = %cond.end90
23 %7 = tail call i64 @llvm.objectsize.i64.p0i8(i8* undef, i1 false)
24 br label %return
25
26 return: ; preds = %if.then172, %cond.end90, %entry
27 ret void
28 }
29
30 ; Function Attrs: nounwind readnone
31 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) #1
32
33 attributes #0 = { nounwind ssp "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
34 attributes #1 = { nounwind readnone }
35
36 !1 = metadata !{metadata !2, metadata !2, i64 0}
37 !2 = metadata !{metadata !"double", metadata !3, i64 0}
38 !3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0}
39 !4 = metadata !{metadata !"Simple C/C++ TBAA"}