[llvm] ff6d333 - [RISCV] Prevent tryToFoldBNEOnCmpXchgResult from deleting AND if it has others users.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 28 10:11:34 PDT 2023


Author: Craig Topper
Date: 2023-08-28T10:11:12-07:00
New Revision: ff6d33382faf3709fa270ae0abb8d165142df9ae

URL: https://github.com/llvm/llvm-project/commit/ff6d33382faf3709fa270ae0abb8d165142df9ae
DIFF: https://github.com/llvm/llvm-project/commit/ff6d33382faf3709fa270ae0abb8d165142df9ae.diff

LOG: [RISCV] Prevent tryToFoldBNEOnCmpXchgResult from deleting AND if it has others users.

This disables the transform if the branch does not have the kill
flag set for the AND we want to delete.

Ideally we'd be able to share the AND with the AND we create in
the expansion, but that's a more complex transform. So this starts
with the simple approach to fix miscompile.

This should be backported to LLVM 17.

Fixes PR65025.ll

Reviewed By: asb

Differential Revision: https://reviews.llvm.org/D158962

Added: 
    llvm/test/CodeGen/RISCV/pr65025.ll

Modified: 
    llvm/lib/Target/RISCV/RISCVExpandAtomicPseudoInsts.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVExpandAtomicPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandAtomicPseudoInsts.cpp
index 353a4c7bde2ff6..bb772fc5da9224 100644
--- a/llvm/lib/Target/RISCV/RISCVExpandAtomicPseudoInsts.cpp
+++ b/llvm/lib/Target/RISCV/RISCVExpandAtomicPseudoInsts.cpp
@@ -601,6 +601,15 @@ bool tryToFoldBNEOnCmpXchgResult(MachineBasicBlock &MBB,
   if (!(BNEOp0 == DestReg && BNEOp1 == CmpValReg) &&
       !(BNEOp0 == CmpValReg && BNEOp1 == DestReg))
     return false;
+
+  // Make sure the branch is the only user of the AND.
+  if (MaskReg.isValid()) {
+    if (BNEOp0 == DestReg && !MBBI->getOperand(0).isKill())
+      return false;
+    if (BNEOp1 == DestReg && !MBBI->getOperand(1).isKill())
+      return false;
+  }
+
   ToErase.push_back(&*MBBI);
   LoopHeadBNETarget = MBBI->getOperand(2).getMBB();
   MBBI = skipDebugInstructionsForward(std::next(MBBI), E);

diff  --git a/llvm/test/CodeGen/RISCV/pr65025.ll b/llvm/test/CodeGen/RISCV/pr65025.ll
new file mode 100644
index 00000000000000..dcd71edc460b8d
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/pr65025.ll
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc < %s -mtriple=riscv64 -mattr=+a | FileCheck %s
+
+define ptr @cmpxchg_masked_and_branch1(ptr %ptr, i8 signext %cmp, i8 signext %val) nounwind {
+; CHECK-LABEL: cmpxchg_masked_and_branch1:
+; CHECK:       # %bb.0: # %do_cmpxchg
+; CHECK-NEXT:    andi a3, a0, -4
+; CHECK-NEXT:    slli a4, a0, 3
+; CHECK-NEXT:    li a5, 255
+; CHECK-NEXT:    sllw a5, a5, a4
+; CHECK-NEXT:    andi a1, a1, 255
+; CHECK-NEXT:    sllw a1, a1, a4
+; CHECK-NEXT:    andi a2, a2, 255
+; CHECK-NEXT:    sllw a2, a2, a4
+; CHECK-NEXT:  .LBB0_3: # %do_cmpxchg
+; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:    lr.w.aqrl a4, (a3)
+; CHECK-NEXT:    and a6, a4, a5
+; CHECK-NEXT:    bne a6, a1, .LBB0_5
+; CHECK-NEXT:  # %bb.4: # %do_cmpxchg
+; CHECK-NEXT:    # in Loop: Header=BB0_3 Depth=1
+; CHECK-NEXT:    xor a6, a4, a2
+; CHECK-NEXT:    and a6, a6, a5
+; CHECK-NEXT:    xor a6, a4, a6
+; CHECK-NEXT:    sc.w.rl a6, a6, (a3)
+; CHECK-NEXT:    bnez a6, .LBB0_3
+; CHECK-NEXT:  .LBB0_5: # %do_cmpxchg
+; CHECK-NEXT:    and a2, a4, a5
+; CHECK-NEXT:    bne a1, a2, .LBB0_2
+; CHECK-NEXT:  # %bb.1: # %returnptr
+; CHECK-NEXT:    xor a1, a1, a2
+; CHECK-NEXT:    snez a1, a1
+; CHECK-NEXT:    addi a1, a1, -1
+; CHECK-NEXT:    and a0, a1, a0
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB0_2: # %exit
+; CHECK-NEXT:    li a0, 0
+; CHECK-NEXT:    ret
+do_cmpxchg:
+  %0 = cmpxchg ptr %ptr, i8 %cmp, i8 %val seq_cst seq_cst
+  %1 = extractvalue { i8, i1 } %0, 1
+  %2 = select i1 %1, ptr %ptr, ptr null
+  br i1 %1, label %returnptr, label %exit
+returnptr:
+  ret ptr %2
+exit:
+  ret ptr null
+}


        


More information about the llvm-commits mailing list