llvm.org GIT mirror llvm / 13422af
Merging r277755: ------------------------------------------------------------------------ r277755 | tnorthover | 2016-08-04 12:32:28 -0700 (Thu, 04 Aug 2016) | 5 lines AArch64: don't assume all i128s are BUILD_PAIRs It leads to a crash when they're not. I'm *sure* I've made this mistake before, at least once. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_39@288845 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 2 years ago
2 changed file(s) with 39 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
1008210082 Results.push_back(SplitVal);
1008310083 }
1008410084
10085 static std::pair splitInt128(SDValue N, SelectionDAG &DAG) {
10086 SDLoc DL(N);
10087 SDValue Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::i64, N);
10088 SDValue Hi = DAG.getNode(ISD::TRUNCATE, DL, MVT::i64,
10089 DAG.getNode(ISD::SRL, DL, MVT::i128, N,
10090 DAG.getConstant(64, DL, MVT::i64)));
10091 return std::make_pair(Lo, Hi);
10092 }
10093
1008510094 static void ReplaceCMP_SWAP_128Results(SDNode *N,
1008610095 SmallVectorImpl & Results,
1008710096 SelectionDAG &DAG) {
1008810097 assert(N->getValueType(0) == MVT::i128 &&
1008910098 "AtomicCmpSwap on types less than 128 should be legal");
10090 SDValue Ops[] = {N->getOperand(1),
10091 N->getOperand(2)->getOperand(0),
10092 N->getOperand(2)->getOperand(1),
10093 N->getOperand(3)->getOperand(0),
10094 N->getOperand(3)->getOperand(1),
10095 N->getOperand(0)};
10099 auto Desired = splitInt128(N->getOperand(2), DAG);
10100 auto New = splitInt128(N->getOperand(3), DAG);
10101 SDValue Ops[] = {N->getOperand(1), Desired.first, Desired.second,
10102 New.first, New.second, N->getOperand(0)};
1009610103 SDNode *CmpSwap = DAG.getMachineNode(
1009710104 AArch64::CMP_SWAP_128, SDLoc(N),
1009810105 DAG.getVTList(MVT::i64, MVT::i64, MVT::i32, MVT::Other), Ops);
7272 %res = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst monotonic
7373 ret { i128, i1 } %res
7474 }
75
76 ; Original implementation assumed the desired & new arguments had already been
77 ; type-legalized into some kind of BUILD_PAIR operation and crashed when this
78 ; was false.
79 @var128 = global i128 0
80 define {i128, i1} @test_cmpxchg_128_unsplit(i128* %addr) {
81 ; CHECK-LABEL: test_cmpxchg_128_unsplit:
82 ; CHECK: add x[[VAR128:[0-9]+]], {{x[0-9]+}}, :lo12:var128
83 ; CHECK: ldr [[DESIRED_HI:x[0-9]+]], [x[[VAR128]], #8]
84 ; CHECK: ldr [[DESIRED_LO:x[0-9]+]], [x[[VAR128]]]
85 ; CHECK: ldr [[NEW_HI:x[0-9]+]], [x[[VAR128]], #8]
86 ; CHECK: ldr [[NEW_LO:x[0-9]+]], [x[[VAR128]]]
87 ; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]:
88 ; CHECK: ldaxp [[OLD_LO:x[0-9]+]], [[OLD_HI:x[0-9]+]], [x0]
89 ; CHECK: cmp [[OLD_LO]], [[DESIRED_LO]]
90 ; CHECK: sbcs xzr, [[OLD_HI]], [[DESIRED_HI]]
91 ; CHECK: b.ne [[DONE:.LBB[0-9]+_[0-9]+]]
92 ; CHECK: stlxp [[STATUS:w[0-9]+]], [[NEW_LO]], [[NEW_HI]], [x0]
93 ; CHECK: cbnz [[STATUS]], [[RETRY]]
94 ; CHECK: [[DONE]]:
95
96 %desired = load volatile i128, i128* @var128
97 %new = load volatile i128, i128* @var128
98 %val = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst
99 ret { i128, i1 } %val
100 }