diff options
author | Alex Bradbury <asb@asbradbury.org> | 2020-06-25 11:38:33 +0100 |
---|---|---|
committer | Tom Stellard <tstellar@redhat.com> | 2020-06-25 16:13:53 -0700 |
commit | f8e49af4f1adcf457ea32e7164a126b10357cf4f (patch) | |
tree | dfde209b720b11d3f5c384ea2e12c6e12557f9a7 | |
parent | 9bf7ca2c92a8c78129e503956cc4c6e9db13bec5 (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.
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 14 | ||||
-rw-r--r-- | llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll | 10 |
2 files changed, 23 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( diff --git a/llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll b/llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll index 43da05ebe7c7..f2691ba1a771 100644 --- a/llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll +++ b/llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll @@ -1628,6 +1628,7 @@ define void @cmpxchg_i32_monotonic_monotonic(i32* %ptr, i32 %cmp, i32 %val) noun ; ; RV64IA-LABEL: cmpxchg_i32_monotonic_monotonic: ; RV64IA: # %bb.0: +; RV64IA-NEXT: sext.w a1, a1 ; RV64IA-NEXT: .LBB20_1: # =>This Inner Loop Header: Depth=1 ; RV64IA-NEXT: lr.w a3, (a0) ; RV64IA-NEXT: bne a3, a1, .LBB20_3 @@ -1680,6 +1681,7 @@ define void @cmpxchg_i32_acquire_monotonic(i32* %ptr, i32 %cmp, i32 %val) nounwi ; ; RV64IA-LABEL: cmpxchg_i32_acquire_monotonic: ; RV64IA: # %bb.0: +; RV64IA-NEXT: sext.w a1, a1 ; RV64IA-NEXT: .LBB21_1: # =>This Inner Loop Header: Depth=1 ; RV64IA-NEXT: lr.w.aq a3, (a0) ; RV64IA-NEXT: bne a3, a1, .LBB21_3 @@ -1732,6 +1734,7 @@ define void @cmpxchg_i32_acquire_acquire(i32* %ptr, i32 %cmp, i32 %val) nounwind ; ; RV64IA-LABEL: cmpxchg_i32_acquire_acquire: ; RV64IA: # %bb.0: +; RV64IA-NEXT: sext.w a1, a1 ; RV64IA-NEXT: .LBB22_1: # =>This Inner Loop Header: Depth=1 ; RV64IA-NEXT: lr.w.aq a3, (a0) ; RV64IA-NEXT: bne a3, a1, .LBB22_3 @@ -1784,6 +1787,7 @@ define void @cmpxchg_i32_release_monotonic(i32* %ptr, i32 %cmp, i32 %val) nounwi ; ; RV64IA-LABEL: cmpxchg_i32_release_monotonic: ; RV64IA: # %bb.0: +; RV64IA-NEXT: sext.w a1, a1 ; RV64IA-NEXT: .LBB23_1: # =>This Inner Loop Header: Depth=1 ; RV64IA-NEXT: lr.w a3, (a0) ; RV64IA-NEXT: bne a3, a1, .LBB23_3 @@ -1836,6 +1840,7 @@ define void @cmpxchg_i32_release_acquire(i32* %ptr, i32 %cmp, i32 %val) nounwind ; ; RV64IA-LABEL: cmpxchg_i32_release_acquire: ; RV64IA: # %bb.0: +; RV64IA-NEXT: sext.w a1, a1 ; RV64IA-NEXT: .LBB24_1: # =>This Inner Loop Header: Depth=1 ; RV64IA-NEXT: lr.w a3, (a0) ; RV64IA-NEXT: bne a3, a1, .LBB24_3 @@ -1888,6 +1893,7 @@ define void @cmpxchg_i32_acq_rel_monotonic(i32* %ptr, i32 %cmp, i32 %val) nounwi ; ; RV64IA-LABEL: cmpxchg_i32_acq_rel_monotonic: ; RV64IA: # %bb.0: +; RV64IA-NEXT: sext.w a1, a1 ; RV64IA-NEXT: .LBB25_1: # =>This Inner Loop Header: Depth=1 ; RV64IA-NEXT: lr.w.aq a3, (a0) ; RV64IA-NEXT: bne a3, a1, .LBB25_3 @@ -1940,6 +1946,7 @@ define void @cmpxchg_i32_acq_rel_acquire(i32* %ptr, i32 %cmp, i32 %val) nounwind ; ; RV64IA-LABEL: cmpxchg_i32_acq_rel_acquire: ; RV64IA: # %bb.0: +; RV64IA-NEXT: sext.w a1, a1 ; RV64IA-NEXT: .LBB26_1: # =>This Inner Loop Header: Depth=1 ; RV64IA-NEXT: lr.w.aq a3, (a0) ; RV64IA-NEXT: bne a3, a1, .LBB26_3 @@ -1992,6 +1999,7 @@ define void @cmpxchg_i32_seq_cst_monotonic(i32* %ptr, i32 %cmp, i32 %val) nounwi ; ; RV64IA-LABEL: cmpxchg_i32_seq_cst_monotonic: ; RV64IA: # %bb.0: +; RV64IA-NEXT: sext.w a1, a1 ; RV64IA-NEXT: .LBB27_1: # =>This Inner Loop Header: Depth=1 ; RV64IA-NEXT: lr.w.aqrl a3, (a0) ; RV64IA-NEXT: bne a3, a1, .LBB27_3 @@ -2044,6 +2052,7 @@ define void @cmpxchg_i32_seq_cst_acquire(i32* %ptr, i32 %cmp, i32 %val) nounwind ; ; RV64IA-LABEL: cmpxchg_i32_seq_cst_acquire: ; RV64IA: # %bb.0: +; RV64IA-NEXT: sext.w a1, a1 ; RV64IA-NEXT: .LBB28_1: # =>This Inner Loop Header: Depth=1 ; RV64IA-NEXT: lr.w.aqrl a3, (a0) ; RV64IA-NEXT: bne a3, a1, .LBB28_3 @@ -2096,6 +2105,7 @@ define void @cmpxchg_i32_seq_cst_seq_cst(i32* %ptr, i32 %cmp, i32 %val) nounwind ; ; RV64IA-LABEL: cmpxchg_i32_seq_cst_seq_cst: ; RV64IA: # %bb.0: +; RV64IA-NEXT: sext.w a1, a1 ; RV64IA-NEXT: .LBB29_1: # =>This Inner Loop Header: Depth=1 ; RV64IA-NEXT: lr.w.aqrl a3, (a0) ; RV64IA-NEXT: bne a3, a1, .LBB29_3 |