[PATCH] D19651: [mips][atomics] Fix partword atomic binary operation implementation

Simon Dardis via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 28 03:00:43 PDT 2016


sdardis created this revision.
sdardis added a reviewer: dsanders.
sdardis added a subscriber: llvm-commits.
sdardis set the repository for this revision to rL LLVM.
Herald added a reviewer: vkalintiris.
Herald added subscribers: sdardis, dsanders.

Currently Mips::emitAtomicBinaryPartword() does not properly respect the
width of pointers. For MIPS64 this causes the memory address that the ll/sc
sequence uses to be truncated. At runtime this causes a segmentation fault.

This can be fixed by applying similar changes as D18995, so that a full 64bit
pointer is loaded.


Repository:
  rL LLVM

http://reviews.llvm.org/D19651

Files:
  lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
  lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
  lib/Target/Mips/MipsISelLowering.cpp
  test/CodeGen/Mips/atomicrmw.ll

Index: test/CodeGen/Mips/atomicrmw.ll
===================================================================
--- /dev/null
+++ test/CodeGen/Mips/atomicrmw.ll
@@ -0,0 +1,19 @@
+; RUN: llc -O0 -march=mipsel -mcpu=mips32r2 -target-abi=o32 < %s -filetype=asm -o - \
+; RUN:   | FileCheck -check-prefix=PTR32 -check-prefix=ALL %s
+; RUN: llc -O0 -march=mips64el -mcpu=mips64r2 -target-abi=n32 < %s -filetype=asm -o - \
+; RUN:   | FileCheck  -check-prefix=PTR32 -check-prefix=ALL %s
+; RUN: llc -O0 -march=mips64el -mcpu=mips64r2 -target-abi=n64 < %s -filetype=asm -o - \
+; RUN:   | FileCheck -check-prefix=PTR64 -check-prefix=ALL %s
+
+define i16 @f(i16* %t, i16 zeroext %v) {
+; ALL-LABEL: f
+entry:
+; PTR32: lw $[[R0:[0-9]+]]
+; PTR64: ld $[[R0:[0-9]+]]
+
+; ALL: ll ${{[0-9]+}}, 0($[[R0]])
+
+   %t.addr = alloca i16*, align 8
+   %ret = atomicrmw add i16* %t, i16 %v monotonic
+  ret i16 %ret
+}
Index: lib/Target/Mips/MipsISelLowering.cpp
===================================================================
--- lib/Target/Mips/MipsISelLowering.cpp
+++ lib/Target/Mips/MipsISelLowering.cpp
@@ -1225,21 +1225,24 @@
   MachineFunction *MF = BB->getParent();
   MachineRegisterInfo &RegInfo = MF->getRegInfo();
   const TargetRegisterClass *RC = getRegClassFor(MVT::i32);
+  bool ArePtrs64bit = ABI.ArePtrs64bit();
+  const TargetRegisterClass *RCp =
+    getRegClassFor(ArePtrs64bit ? MVT::i64 : MVT::i32);
   const TargetInstrInfo *TII = Subtarget.getInstrInfo();
   DebugLoc DL = MI->getDebugLoc();
 
   unsigned Dest = MI->getOperand(0).getReg();
   unsigned Ptr = MI->getOperand(1).getReg();
   unsigned Incr = MI->getOperand(2).getReg();
 
-  unsigned AlignedAddr = RegInfo.createVirtualRegister(RC);
+  unsigned AlignedAddr = RegInfo.createVirtualRegister(RCp);
   unsigned ShiftAmt = RegInfo.createVirtualRegister(RC);
   unsigned Mask = RegInfo.createVirtualRegister(RC);
   unsigned Mask2 = RegInfo.createVirtualRegister(RC);
   unsigned NewVal = RegInfo.createVirtualRegister(RC);
   unsigned OldVal = RegInfo.createVirtualRegister(RC);
   unsigned Incr2 = RegInfo.createVirtualRegister(RC);
-  unsigned MaskLSB2 = RegInfo.createVirtualRegister(RC);
+  unsigned MaskLSB2 = RegInfo.createVirtualRegister(RCp);
   unsigned PtrLSB2 = RegInfo.createVirtualRegister(RC);
   unsigned MaskUpper = RegInfo.createVirtualRegister(RC);
   unsigned AndRes = RegInfo.createVirtualRegister(RC);
@@ -1281,11 +1284,12 @@
   //    sll     incr2,incr,shiftamt
 
   int64_t MaskImm = (Size == 1) ? 255 : 65535;
-  BuildMI(BB, DL, TII->get(Mips::ADDiu), MaskLSB2)
-    .addReg(Mips::ZERO).addImm(-4);
-  BuildMI(BB, DL, TII->get(Mips::AND), AlignedAddr)
+  BuildMI(BB, DL, TII->get(ABI.GetPtrAddiuOp()), MaskLSB2)
+    .addReg(ABI.GetNullPtr()).addImm(-4);
+  BuildMI(BB, DL, TII->get(ABI.GetPtrAndOp()), AlignedAddr)
     .addReg(Ptr).addReg(MaskLSB2);
-  BuildMI(BB, DL, TII->get(Mips::ANDi), PtrLSB2).addReg(Ptr).addImm(3);
+  BuildMI(BB, DL, TII->get(Mips::ANDi), PtrLSB2)
+      .addReg(Ptr, 0, ArePtrs64bit ? Mips::sub_32 : 0 ).addImm(3);
   if (Subtarget.isLittle()) {
     BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3);
   } else {
Index: lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
===================================================================
--- lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
+++ lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
@@ -70,6 +70,7 @@
   unsigned GetZeroReg() const;
   unsigned GetPtrAdduOp() const;
   unsigned GetPtrAddiuOp() const;
+  unsigned GetPtrAndOp() const;
   unsigned GetGPRMoveOp() const;
   inline bool ArePtrs64bit() const { return IsN64(); }
   inline bool AreGprs64bit() const { return IsN32() || IsN64(); }
Index: lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
===================================================================
--- lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
+++ lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
@@ -118,6 +118,10 @@
   return ArePtrs64bit() ? Mips::DADDiu : Mips::ADDiu;
 }
 
+unsigned MipsABIInfo::GetPtrAndOp() const {
+  return ArePtrs64bit() ? Mips::AND64 : Mips::AND;
+}
+
 unsigned MipsABIInfo::GetGPRMoveOp() const {
   return ArePtrs64bit() ? Mips::OR64 : Mips::OR;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D19651.55391.patch
Type: text/x-patch
Size: 4175 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160428/a211f75b/attachment.bin>


More information about the llvm-commits mailing list