[llvm-branch-commits] [llvm-branch] r288845 - Merging r277755:

Tom Stellard via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Dec 6 12:09:31 PST 2016


Author: tstellar
Date: Tue Dec  6 14:09:30 2016
New Revision: 288845

URL: http://llvm.org/viewvc/llvm-project?rev=288845&view=rev
Log:
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.

------------------------------------------------------------------------

Modified:
    llvm/branches/release_39/lib/Target/AArch64/AArch64ISelLowering.cpp
    llvm/branches/release_39/test/CodeGen/AArch64/cmpxchg-O0.ll

Modified: llvm/branches/release_39/lib/Target/AArch64/AArch64ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_39/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=288845&r1=288844&r2=288845&view=diff
==============================================================================
--- llvm/branches/release_39/lib/Target/AArch64/AArch64ISelLowering.cpp (original)
+++ llvm/branches/release_39/lib/Target/AArch64/AArch64ISelLowering.cpp Tue Dec  6 14:09:30 2016
@@ -10083,17 +10083,24 @@ static void ReplaceReductionResults(SDNo
   Results.push_back(SplitVal);
 }
 
+static std::pair<SDValue, SDValue> splitInt128(SDValue N, SelectionDAG &DAG) {
+  SDLoc DL(N);
+  SDValue Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::i64, N);
+  SDValue Hi = DAG.getNode(ISD::TRUNCATE, DL, MVT::i64,
+                           DAG.getNode(ISD::SRL, DL, MVT::i128, N,
+                                       DAG.getConstant(64, DL, MVT::i64)));
+  return std::make_pair(Lo, Hi);
+}
+
 static void ReplaceCMP_SWAP_128Results(SDNode *N,
                                        SmallVectorImpl<SDValue> & Results,
                                        SelectionDAG &DAG) {
   assert(N->getValueType(0) == MVT::i128 &&
          "AtomicCmpSwap on types less than 128 should be legal");
-  SDValue Ops[] = {N->getOperand(1),
-                   N->getOperand(2)->getOperand(0),
-                   N->getOperand(2)->getOperand(1),
-                   N->getOperand(3)->getOperand(0),
-                   N->getOperand(3)->getOperand(1),
-                   N->getOperand(0)};
+  auto Desired = splitInt128(N->getOperand(2), DAG);
+  auto New = splitInt128(N->getOperand(3), DAG);
+  SDValue Ops[] = {N->getOperand(1), Desired.first, Desired.second,
+                   New.first,        New.second,    N->getOperand(0)};
   SDNode *CmpSwap = DAG.getMachineNode(
       AArch64::CMP_SWAP_128, SDLoc(N),
       DAG.getVTList(MVT::i64, MVT::i64, MVT::i32, MVT::Other), Ops);

Modified: llvm/branches/release_39/test/CodeGen/AArch64/cmpxchg-O0.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_39/test/CodeGen/AArch64/cmpxchg-O0.ll?rev=288845&r1=288844&r2=288845&view=diff
==============================================================================
--- llvm/branches/release_39/test/CodeGen/AArch64/cmpxchg-O0.ll (original)
+++ llvm/branches/release_39/test/CodeGen/AArch64/cmpxchg-O0.ll Tue Dec  6 14:09:30 2016
@@ -73,3 +73,29 @@ define { i128, i1 } @test_cmpxchg_128(i1
   %res = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst monotonic
   ret { i128, i1 } %res
 }
+
+; Original implementation assumed the desired & new arguments had already been
+; type-legalized into some kind of BUILD_PAIR operation and crashed when this
+; was false.
+ at var128 = global i128 0
+define {i128, i1} @test_cmpxchg_128_unsplit(i128* %addr) {
+; CHECK-LABEL: test_cmpxchg_128_unsplit:
+; CHECK:     add x[[VAR128:[0-9]+]], {{x[0-9]+}}, :lo12:var128
+; CHECK:     ldr [[DESIRED_HI:x[0-9]+]], [x[[VAR128]], #8]
+; CHECK:     ldr [[DESIRED_LO:x[0-9]+]], [x[[VAR128]]]
+; CHECK:     ldr [[NEW_HI:x[0-9]+]], [x[[VAR128]], #8]
+; CHECK:     ldr [[NEW_LO:x[0-9]+]], [x[[VAR128]]]
+; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]:
+; CHECK:     ldaxp [[OLD_LO:x[0-9]+]], [[OLD_HI:x[0-9]+]], [x0]
+; CHECK:     cmp [[OLD_LO]], [[DESIRED_LO]]
+; CHECK:     sbcs xzr, [[OLD_HI]], [[DESIRED_HI]]
+; CHECK:     b.ne [[DONE:.LBB[0-9]+_[0-9]+]]
+; CHECK:     stlxp [[STATUS:w[0-9]+]], [[NEW_LO]], [[NEW_HI]], [x0]
+; CHECK:     cbnz [[STATUS]], [[RETRY]]
+; CHECK: [[DONE]]:
+
+  %desired = load volatile i128, i128* @var128
+  %new = load volatile i128, i128* @var128
+  %val = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst
+  ret { i128, i1 } %val
+}




More information about the llvm-branch-commits mailing list