[llvm] r322988 - [SystemZ] Directly use CC result of compare-and-swap
Ulrich Weigand via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 19 12:54:18 PST 2018
Author: uweigand
Date: Fri Jan 19 12:54:18 2018
New Revision: 322988
URL: http://llvm.org/viewvc/llvm-project?rev=322988&view=rev
Log:
[SystemZ] Directly use CC result of compare-and-swap
In order to implement a test whether a compare-and-swap succeeded, the
SystemZ back-end currently emits a rather inefficient sequence of first
converting the CC result into an integer, and then testing that integer
against zero. This commit changes the back-end to simply directly test
the CC value set by the compare-and-swap instruction.
Modified:
llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp
llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h
llvm/trunk/test/CodeGen/SystemZ/cmpxchg-01.ll
llvm/trunk/test/CodeGen/SystemZ/cmpxchg-02.ll
llvm/trunk/test/CodeGen/SystemZ/cmpxchg-03.ll
llvm/trunk/test/CodeGen/SystemZ/cmpxchg-04.ll
llvm/trunk/test/CodeGen/SystemZ/cmpxchg-06.ll
Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp?rev=322988&r1=322987&r2=322988&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp Fri Jan 19 12:54:18 2018
@@ -2161,6 +2161,24 @@ static void adjustForTestUnderMask(Selec
C.CCMask = NewCCMask;
}
+// See whether the comparison argument contains a redundant AND
+// and remove it if so. This sometimes happens due to the generic
+// BRCOND expansion.
+static void adjustForRedundantAnd(SelectionDAG &DAG, const SDLoc &DL,
+ Comparison &C) {
+ if (C.Op0.getOpcode() != ISD::AND)
+ return;
+ auto *Mask = dyn_cast<ConstantSDNode>(C.Op0.getOperand(1));
+ if (!Mask)
+ return;
+ KnownBits Known;
+ DAG.computeKnownBits(C.Op0.getOperand(0), Known);
+ if ((~Known.Zero).getZExtValue() & ~Mask->getZExtValue())
+ return;
+
+ C.Op0 = C.Op0.getOperand(0);
+}
+
// Return a Comparison that tests the condition-code result of intrinsic
// node Call against constant integer CC using comparison code Cond.
// Opcode is the opcode of the SystemZISD operation for the intrinsic
@@ -2235,6 +2253,7 @@ static Comparison getCmp(SelectionDAG &D
else
C.ICmpType = SystemZICMP::SignedOnly;
C.CCMask &= ~SystemZ::CCMASK_CMP_UO;
+ adjustForRedundantAnd(DAG, DL, C);
adjustZeroCmp(DAG, DL, C);
adjustSubwordCmp(DAG, DL, C);
adjustForSubtraction(DAG, DL, C);
@@ -5409,6 +5428,109 @@ SDValue SystemZTargetLowering::combineSH
return SDValue();
}
+static bool combineCCMask(SDValue &Glue, int &CCValid, int &CCMask) {
+ // We have a SELECT_CCMASK or BR_CCMASK comparing the condition code
+ // set by the glued instruction using the CCValid / CCMask masks,
+ // If the glued instruction is itself a (ICMP (SELECT_CCMASK)) testing
+ // the condition code set by some other instruction, see whether we
+ // can directly use that condition code.
+ bool Invert = false;
+
+ // Verify that we have an appropriate mask for a EQ or NE comparison.
+ if (CCValid != SystemZ::CCMASK_ICMP)
+ return false;
+ if (CCMask == SystemZ::CCMASK_CMP_NE)
+ Invert = !Invert;
+ else if (CCMask != SystemZ::CCMASK_CMP_EQ)
+ return false;
+
+ // Verify that we have an ICMP that is the single user of a SELECT_CCMASK.
+ SDNode *ICmp = Glue.getNode();
+ if (ICmp->getOpcode() != SystemZISD::ICMP)
+ return false;
+ SDNode *Select = ICmp->getOperand(0).getNode();
+ if (Select->getOpcode() != SystemZISD::SELECT_CCMASK)
+ return false;
+ if (!Select->hasOneUse())
+ return false;
+
+ // Verify that the ICMP compares against one of select values.
+ auto *CompareVal = dyn_cast<ConstantSDNode>(ICmp->getOperand(1));
+ if (!CompareVal)
+ return false;
+ auto *TrueVal = dyn_cast<ConstantSDNode>(Select->getOperand(0));
+ if (!TrueVal)
+ return false;
+ auto *FalseVal = dyn_cast<ConstantSDNode>(Select->getOperand(1));
+ if (!FalseVal)
+ return false;
+ if (CompareVal->getZExtValue() == FalseVal->getZExtValue())
+ Invert = !Invert;
+ else if (CompareVal->getZExtValue() != TrueVal->getZExtValue())
+ return false;
+
+ // Compute the effective CC mask for the new branch or select.
+ auto *NewCCValid = dyn_cast<ConstantSDNode>(Select->getOperand(2));
+ auto *NewCCMask = dyn_cast<ConstantSDNode>(Select->getOperand(3));
+ if (!NewCCValid || !NewCCMask)
+ return false;
+ CCValid = NewCCValid->getZExtValue();
+ CCMask = NewCCMask->getZExtValue();
+ if (Invert)
+ CCMask ^= CCValid;
+
+ // Return the updated Glue link.
+ Glue = Select->getOperand(4);
+ return true;
+}
+
+SDValue SystemZTargetLowering::combineBR_CCMASK(
+ SDNode *N, DAGCombinerInfo &DCI) const {
+ SelectionDAG &DAG = DCI.DAG;
+
+ // Combine BR_CCMASK (ICMP (SELECT_CCMASK)) into a single BR_CCMASK.
+ auto *CCValid = dyn_cast<ConstantSDNode>(N->getOperand(1));
+ auto *CCMask = dyn_cast<ConstantSDNode>(N->getOperand(2));
+ if (!CCValid || !CCMask)
+ return SDValue();
+
+ int CCValidVal = CCValid->getZExtValue();
+ int CCMaskVal = CCMask->getZExtValue();
+ SDValue Glue = N->getOperand(4);
+
+ if (combineCCMask(Glue, CCValidVal, CCMaskVal))
+ return DAG.getNode(SystemZISD::BR_CCMASK, SDLoc(N), N->getValueType(0),
+ N->getOperand(0),
+ DAG.getConstant(CCValidVal, SDLoc(N), MVT::i32),
+ DAG.getConstant(CCMaskVal, SDLoc(N), MVT::i32),
+ N->getOperand(3), Glue);
+ return SDValue();
+}
+
+SDValue SystemZTargetLowering::combineSELECT_CCMASK(
+ SDNode *N, DAGCombinerInfo &DCI) const {
+ SelectionDAG &DAG = DCI.DAG;
+
+ // Combine SELECT_CCMASK (ICMP (SELECT_CCMASK)) into a single SELECT_CCMASK.
+ auto *CCValid = dyn_cast<ConstantSDNode>(N->getOperand(2));
+ auto *CCMask = dyn_cast<ConstantSDNode>(N->getOperand(3));
+ if (!CCValid || !CCMask)
+ return SDValue();
+
+ int CCValidVal = CCValid->getZExtValue();
+ int CCMaskVal = CCMask->getZExtValue();
+ SDValue Glue = N->getOperand(4);
+
+ if (combineCCMask(Glue, CCValidVal, CCMaskVal))
+ return DAG.getNode(SystemZISD::SELECT_CCMASK, SDLoc(N), N->getValueType(0),
+ N->getOperand(0),
+ N->getOperand(1),
+ DAG.getConstant(CCValidVal, SDLoc(N), MVT::i32),
+ DAG.getConstant(CCMaskVal, SDLoc(N), MVT::i32),
+ Glue);
+ return SDValue();
+}
+
SDValue SystemZTargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
switch(N->getOpcode()) {
@@ -5427,6 +5549,8 @@ SDValue SystemZTargetLowering::PerformDA
case ISD::SRA:
case ISD::SRL:
case ISD::ROTL: return combineSHIFTROT(N, DCI);
+ case SystemZISD::BR_CCMASK: return combineBR_CCMASK(N, DCI);
+ case SystemZISD::SELECT_CCMASK: return combineSELECT_CCMASK(N, DCI);
}
return SDValue();
Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h?rev=322988&r1=322987&r2=322988&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h Fri Jan 19 12:54:18 2018
@@ -581,6 +581,8 @@ private:
SDValue combineFP_ROUND(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineBSWAP(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineSHIFTROT(SDNode *N, DAGCombinerInfo &DCI) const;
+ SDValue combineBR_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
+ SDValue combineSELECT_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
// If the last instruction before MBBI in MBB was some form of COMPARE,
// try to replace it with a COMPARE AND BRANCH just before MBBI.
Modified: llvm/trunk/test/CodeGen/SystemZ/cmpxchg-01.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/cmpxchg-01.ll?rev=322988&r1=322987&r2=322988&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/cmpxchg-01.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/cmpxchg-01.ll Fri Jan 19 12:54:18 2018
@@ -89,3 +89,83 @@ define i32 @f3(i8 %dummy, i8 *%src, i8 %
ret i32 %res
}
+
+declare void @g()
+
+; Check using the comparison result for a branch.
+; CHECK-LABEL: f4
+; CHECK-MAIN-LABEL: f4:
+; CHECK-MAIN: risbg [[RISBG:%r[1-9]+]], %r2, 0, 189, 0{{$}}
+; CHECK-MAIN-DAG: sll %r2, 3
+; CHECK-MAIN-DAG: l [[OLD:%r[0-9]+]], 0([[RISBG]])
+; CHECK-MAIN: [[LOOP:\.[^ ]*]]:
+; CHECK-MAIN: rll [[TMP:%r[0-9]+]], [[OLD]], 8(%r2)
+; CHECK-MAIN: risbg %r3, [[TMP]], 32, 55, 0
+; CHECK-MAIN: cr [[TMP]], %r3
+; CHECK-MAIN: jlh [[EXIT:\.[^ ]*]]
+; CHECK-MAIN: risbg %r4, [[TMP]], 32, 55, 0
+; CHECK-MAIN: rll [[NEW:%r[0-9]+]], %r4, -8({{%r[1-9]+}})
+; CHECK-MAIN: cs [[OLD]], [[NEW]], 0([[RISBG]])
+; CHECK-MAIN: jl [[LOOP]]
+; CHECK-MAIN: [[EXIT]]:
+; CHECK-MAIN-NEXT: jlh [[LABEL:\.[^ ]*]]
+; CHECK-MAIN: jg g
+; CHECK-MAIN: [[LABEL]]:
+; CHECK-MAIN: br %r14
+;
+; CHECK-SHIFT-LABEL: f4:
+; CHECK-SHIFT: sll %r2, 3
+; CHECK-SHIFT: lcr [[NEGSHIFT:%r[1-9]+]], %r2
+; CHECK-SHIFT: rll
+; CHECK-SHIFT: rll {{%r[0-9]+}}, %r4, -8([[NEGSHIFT]])
+define void @f4(i8 *%src, i8 %cmp, i8 %swap) {
+ %pair = cmpxchg i8 *%src, i8 %cmp, i8 %swap seq_cst seq_cst
+ %cond = extractvalue { i8, i1 } %pair, 1
+ br i1 %cond, label %call, label %exit
+
+call:
+ tail call void @g()
+ br label %exit
+
+exit:
+ ret void
+}
+
+; ... and the same with the inverted direction.
+; CHECK-MAIN-LABEL: f5:
+; CHECK-MAIN: risbg [[RISBG:%r[1-9]+]], %r2, 0, 189, 0{{$}}
+; CHECK-MAIN-DAG: sll %r2, 3
+; CHECK-MAIN-DAG: l [[OLD:%r[0-9]+]], 0([[RISBG]])
+; CHECK-MAIN: [[LOOP:\.[^ ]*]]:
+; CHECK-MAIN: rll [[TMP:%r[0-9]+]], [[OLD]], 8(%r2)
+; CHECK-MAIN: risbg %r3, [[TMP]], 32, 55, 0
+; CHECK-MAIN: cr [[TMP]], %r3
+; CHECK-MAIN: jlh [[EXIT:\.[^ ]*]]
+; CHECK-MAIN: risbg %r4, [[TMP]], 32, 55, 0
+; CHECK-MAIN: rll [[NEW:%r[0-9]+]], %r4, -8({{%r[1-9]+}})
+; CHECK-MAIN: cs [[OLD]], [[NEW]], 0([[RISBG]])
+; CHECK-MAIN: jl [[LOOP]]
+; CHECK-MAIN: [[EXIT]]:
+; CHECK-MAIN-NEXT: jlh [[LABEL:\.[^ ]*]]
+; CHECK-MAIN: br %r14
+; CHECK-MAIN: [[LABEL]]:
+; CHECK-MAIN: jg g
+;
+; CHECK-SHIFT-LABEL: f5:
+; CHECK-SHIFT: sll %r2, 3
+; CHECK-SHIFT: lcr [[NEGSHIFT:%r[1-9]+]], %r2
+; CHECK-SHIFT: rll
+; CHECK-SHIFT: rll {{%r[0-9]+}}, %r4, -8([[NEGSHIFT]])
+define void @f5(i8 *%src, i8 %cmp, i8 %swap) {
+ %pair = cmpxchg i8 *%src, i8 %cmp, i8 %swap seq_cst seq_cst
+ %cond = extractvalue { i8, i1 } %pair, 1
+ br i1 %cond, label %exit, label %call
+
+call:
+ tail call void @g()
+ br label %exit
+
+exit:
+ ret void
+}
+
Modified: llvm/trunk/test/CodeGen/SystemZ/cmpxchg-02.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/cmpxchg-02.ll?rev=322988&r1=322987&r2=322988&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/cmpxchg-02.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/cmpxchg-02.ll Fri Jan 19 12:54:18 2018
@@ -89,3 +89,82 @@ define i32 @f3(i16 %dummy, i16 *%src, i1
ret i32 %res
}
+declare void @g()
+
+; Check using the comparison result for a branch.
+; CHECK-LABEL: f4
+; CHECK-MAIN-LABEL: f4:
+; CHECK-MAIN: risbg [[RISBG:%r[1-9]+]], %r2, 0, 189, 0{{$}}
+; CHECK-MAIN-DAG: sll %r2, 3
+; CHECK-MAIN-DAG: l [[OLD:%r[0-9]+]], 0([[RISBG]])
+; CHECK-MAIN: [[LOOP:\.[^ ]*]]:
+; CHECK-MAIN: rll [[TMP:%r[0-9]+]], [[OLD]], 16(%r2)
+; CHECK-MAIN: risbg %r3, [[TMP]], 32, 47, 0
+; CHECK-MAIN: cr [[TMP]], %r3
+; CHECK-MAIN: jlh [[EXIT:\.[^ ]*]]
+; CHECK-MAIN: risbg %r4, [[TMP]], 32, 47, 0
+; CHECK-MAIN: rll [[NEW:%r[0-9]+]], %r4, -16({{%r[1-9]+}})
+; CHECK-MAIN: cs [[OLD]], [[NEW]], 0([[RISBG]])
+; CHECK-MAIN: jl [[LOOP]]
+; CHECK-MAIN: [[EXIT]]:
+; CHECK-MAIN-NEXT: jlh [[LABEL:\.[^ ]*]]
+; CHECK-MAIN: jg g
+; CHECK-MAIN: [[LABEL]]:
+; CHECK-MAIN: br %r14
+;
+; CHECK-SHIFT-LABEL: f4:
+; CHECK-SHIFT: sll %r2, 3
+; CHECK-SHIFT: lcr [[NEGSHIFT:%r[1-9]+]], %r2
+; CHECK-SHIFT: rll
+; CHECK-SHIFT: rll {{%r[0-9]+}}, %r4, -16([[NEGSHIFT]])
+define void @f4(i16 *%src, i16 %cmp, i16 %swap) {
+ %pair = cmpxchg i16 *%src, i16 %cmp, i16 %swap seq_cst seq_cst
+ %cond = extractvalue { i16, i1 } %pair, 1
+ br i1 %cond, label %call, label %exit
+
+call:
+ tail call void @g()
+ br label %exit
+
+exit:
+ ret void
+}
+
+; ... and the same with the inverted direction.
+; CHECK-MAIN-LABEL: f5:
+; CHECK-MAIN: risbg [[RISBG:%r[1-9]+]], %r2, 0, 189, 0{{$}}
+; CHECK-MAIN-DAG: sll %r2, 3
+; CHECK-MAIN-DAG: l [[OLD:%r[0-9]+]], 0([[RISBG]])
+; CHECK-MAIN: [[LOOP:\.[^ ]*]]:
+; CHECK-MAIN: rll [[TMP:%r[0-9]+]], [[OLD]], 16(%r2)
+; CHECK-MAIN: risbg %r3, [[TMP]], 32, 47, 0
+; CHECK-MAIN: cr [[TMP]], %r3
+; CHECK-MAIN: jlh [[EXIT:\.[^ ]*]]
+; CHECK-MAIN: risbg %r4, [[TMP]], 32, 47, 0
+; CHECK-MAIN: rll [[NEW:%r[0-9]+]], %r4, -16({{%r[1-9]+}})
+; CHECK-MAIN: cs [[OLD]], [[NEW]], 0([[RISBG]])
+; CHECK-MAIN: jl [[LOOP]]
+; CHECK-MAIN: [[EXIT]]:
+; CHECK-MAIN-NEXT: jlh [[LABEL:\.[^ ]*]]
+; CHECK-MAIN: br %r14
+; CHECK-MAIN: [[LABEL]]:
+; CHECK-MAIN: jg g
+;
+; CHECK-SHIFT-LABEL: f5:
+; CHECK-SHIFT: sll %r2, 3
+; CHECK-SHIFT: lcr [[NEGSHIFT:%r[1-9]+]], %r2
+; CHECK-SHIFT: rll
+; CHECK-SHIFT: rll {{%r[0-9]+}}, %r4, -16([[NEGSHIFT]])
+define void @f5(i16 *%src, i16 %cmp, i16 %swap) {
+ %pair = cmpxchg i16 *%src, i16 %cmp, i16 %swap seq_cst seq_cst
+ %cond = extractvalue { i16, i1 } %pair, 1
+ br i1 %cond, label %exit, label %call
+
+call:
+ tail call void @g()
+ br label %exit
+
+exit:
+ ret void
+}
+
Modified: llvm/trunk/test/CodeGen/SystemZ/cmpxchg-03.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/cmpxchg-03.ll?rev=322988&r1=322987&r2=322988&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/cmpxchg-03.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/cmpxchg-03.ll Fri Jan 19 12:54:18 2018
@@ -155,3 +155,42 @@ define i32 @f13(i32 %cmp, i32 %swap, i32
%res = zext i1 %val to i32
ret i32 %res
}
+
+declare void @g()
+
+; Check using the comparison result for a branch.
+; CHECK-LABEL: f14
+; CHECK: cs %r2, %r3, 0(%r4)
+; CHECK-NEXT: jge g
+; CHECK: br %r14
+define void @f14(i32 %cmp, i32 %swap, i32 *%src) {
+ %pairval = cmpxchg i32 *%src, i32 %cmp, i32 %swap seq_cst seq_cst
+ %cond = extractvalue { i32, i1 } %pairval, 1
+ br i1 %cond, label %call, label %exit
+
+call:
+ tail call void @g()
+ br label %exit
+
+exit:
+ ret void
+}
+
+; ... and the same with the inverted direction.
+; CHECK-LABEL: f15
+; CHECK: cs %r2, %r3, 0(%r4)
+; CHECK-NEXT: jgl g
+; CHECK: br %r14
+define void @f15(i32 %cmp, i32 %swap, i32 *%src) {
+ %pairval = cmpxchg i32 *%src, i32 %cmp, i32 %swap seq_cst seq_cst
+ %cond = extractvalue { i32, i1 } %pairval, 1
+ br i1 %cond, label %exit, label %call
+
+call:
+ tail call void @g()
+ br label %exit
+
+exit:
+ ret void
+}
+
Modified: llvm/trunk/test/CodeGen/SystemZ/cmpxchg-04.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/cmpxchg-04.ll?rev=322988&r1=322987&r2=322988&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/cmpxchg-04.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/cmpxchg-04.ll Fri Jan 19 12:54:18 2018
@@ -120,3 +120,41 @@ define i32 @f10(i64 %cmp, i64 %swap, i64
ret i32 %res
}
+declare void @g()
+
+; Check using the comparison result for a branch.
+; CHECK-LABEL: f11
+; CHECK: csg %r2, %r3, 0(%r4)
+; CHECK-NEXT: jge g
+; CHECK: br %r14
+define void @f11(i64 %cmp, i64 %swap, i64 *%src) {
+ %pairval = cmpxchg i64 *%src, i64 %cmp, i64 %swap seq_cst seq_cst
+ %cond = extractvalue { i64, i1 } %pairval, 1
+ br i1 %cond, label %call, label %exit
+
+call:
+ tail call void @g()
+ br label %exit
+
+exit:
+ ret void
+}
+
+; ... and the same with the inverted direction.
+; CHECK-LABEL: f12
+; CHECK: csg %r2, %r3, 0(%r4)
+; CHECK-NEXT: jgl g
+; CHECK: br %r14
+define void @f12(i64 %cmp, i64 %swap, i64 *%src) {
+ %pairval = cmpxchg i64 *%src, i64 %cmp, i64 %swap seq_cst seq_cst
+ %cond = extractvalue { i64, i1 } %pairval, 1
+ br i1 %cond, label %exit, label %call
+
+call:
+ tail call void @g()
+ br label %exit
+
+exit:
+ ret void
+}
+
Modified: llvm/trunk/test/CodeGen/SystemZ/cmpxchg-06.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/cmpxchg-06.ll?rev=322988&r1=322987&r2=322988&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/cmpxchg-06.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/cmpxchg-06.ll Fri Jan 19 12:54:18 2018
@@ -129,3 +129,54 @@ define i32 @f10(i128 %cmp, i128 %swap, i
%res = zext i1 %val to i32
ret i32 %res
}
+
+declare void @g()
+
+; Check using the comparison result for a branch.
+; CHECK-LABEL: f11
+; CHECK-DAG: lg %r1, 8(%r3)
+; CHECK-DAG: lg %r0, 0(%r3)
+; CHECK-DAG: lg %r13, 8(%r2)
+; CHECK-DAG: lg %r12, 0(%r2)
+; CHECK: cdsg %r12, %r0, 0(%r4)
+; CHECK-NEXT: jl [[LABEL:\.[^ ]*]]
+; CHECK: jg g
+; CHECK: [[LABEL]]:
+; CHECK: br %r14
+define void @f11(i128 %cmp, i128 %swap, i128 *%src) {
+ %pairval = cmpxchg i128 *%src, i128 %cmp, i128 %swap seq_cst seq_cst
+ %cond = extractvalue { i128, i1 } %pairval, 1
+ br i1 %cond, label %call, label %exit
+
+call:
+ tail call void @g()
+ br label %exit
+
+exit:
+ ret void
+}
+
+; ... and the same with the inverted direction.
+; CHECK-LABEL: f12
+; CHECK-DAG: lg %r1, 8(%r3)
+; CHECK-DAG: lg %r0, 0(%r3)
+; CHECK-DAG: lg %r13, 8(%r2)
+; CHECK-DAG: lg %r12, 0(%r2)
+; CHECK: cdsg %r12, %r0, 0(%r4)
+; CHECK-NEXT: jl [[LABEL:\.[^ ]*]]
+; CHECK: br %r14
+; CHECK: [[LABEL]]:
+; CHECK: jg g
+define void @f12(i128 %cmp, i128 %swap, i128 *%src) {
+ %pairval = cmpxchg i128 *%src, i128 %cmp, i128 %swap seq_cst seq_cst
+ %cond = extractvalue { i128, i1 } %pairval, 1
+ br i1 %cond, label %exit, label %call
+
+call:
+ tail call void @g()
+ br label %exit
+
+exit:
+ ret void
+}
+
More information about the llvm-commits
mailing list