summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
diff options
context:
space:
mode:
authorAlex Bradbury <asb@asbradbury.org>2020-06-25 11:38:33 +0100
committerTom Stellard <tstellar@redhat.com>2020-06-25 16:13:53 -0700
commitf8e49af4f1adcf457ea32e7164a126b10357cf4f (patch)
treedfde209b720b11d3f5c384ea2e12c6e12557f9a7 /llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
parent9bf7ca2c92a8c78129e503956cc4c6e9db13bec5 (diff)
[LegalizeTypes][RISCV] Correctly sign-extend comparison for ATOMIC_CMP_XCHG
Currently, the comparison argument used for ATOMIC_CMP_XCHG is legalised with GetPromotedInteger, which leaves the upper bits of the value undefind. Since this is used for comparing in an LR/SC loop with a full-width comparison, we must sign extend it on RISC-V. This is related to https://reviews.llvm.org/D58829, which solved the issue for ATOMIC_CMP_SWAP_WITH_SUCCESS, but not the simpler ATOMIC_CMP_SWAP. This patch is a modified form of 616289ed29225c0ddfe5699c7fdf42a0fcbe0ab4 by Jessica Clarke. It localises the changes to LegalizeIntegerTypes and avoids adding a new virtual method to TargetLowering to avoid changing the ABI of libLLVM.so.
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp14
1 files changed, 13 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 6aed5796acc6..015b3d99fb0f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -271,8 +271,20 @@ SDValue DAGTypeLegalizer::PromoteIntRes_AtomicCmpSwap(AtomicSDNode *N,
return Res.getValue(1);
}
- SDValue Op2 = GetPromotedInteger(N->getOperand(2));
+ // Op2 is used for the comparison and thus must be extended according to the
+ // target's atomic operations. Op3 is merely stored and so can be left alone.
+ SDValue Op2 = N->getOperand(2);
SDValue Op3 = GetPromotedInteger(N->getOperand(3));
+ if (TLI.getTargetMachine().getTargetTriple().isRISCV()) {
+ // The comparison argument must be sign-extended for RISC-V. This is
+ // abstracted using a new TargetLowering hook in the main LLVM development
+ // branch, but handled here directly in order to fix the codegen bug for
+ // 10.x without breaking the libLLVM.so ABI.
+ Op2 = SExtPromotedInteger(Op2);
+ } else {
+ Op2 = GetPromotedInteger(Op2);
+ }
+
SDVTList VTs =
DAG.getVTList(Op2.getValueType(), N->getValueType(1), MVT::Other);
SDValue Res = DAG.getAtomicCmpSwap(