[llvm] r267340 - [SystemZ] [SSP] Add support for LOAD_STACK_GUARD.

Marcin Koscielnicki via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 24 06:57:49 PDT 2016


Author: koriakin
Date: Sun Apr 24 08:57:49 2016
New Revision: 267340

URL: http://llvm.org/viewvc/llvm-project?rev=267340&view=rev
Log:
[SystemZ] [SSP] Add support for LOAD_STACK_GUARD.

This fixes PR22248 on s390x.  The previous attempt at this was D19101,
which was before LOAD_STACK_GUARD existed.  Compared to the previous
version, this always emits a rather ugly block of 4 instructions, involving
a thread pointer load that can't be shared with other potential users.
However, this is necessary for SSP - spilling the guard value (or thread
pointer used to load it) is counter to the goal, since it could be
overwritten along with the frame it protects.

Differential Revision: http://reviews.llvm.org/D19363

Added:
    llvm/trunk/test/CodeGen/SystemZ/stack-guard.ll
Modified:
    llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h
    llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp
    llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.h
    llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.h

Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h?rev=267340&r1=267339&r2=267340&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h Sun Apr 24 08:57:49 2016
@@ -426,6 +426,13 @@ public:
     return SystemZ::R7D;
   }
 
+  /// Override to support customized stack guard loading.
+  bool useLoadStackGuardNode() const override {
+    return true;
+  }
+  void insertSSPDeclarations(Module &M) const override {
+  }
+
   MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
                                                  MachineBasicBlock *BB) const
     override;

Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp?rev=267340&r1=267339&r2=267340&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp Sun Apr 24 08:57:49 2016
@@ -160,6 +160,37 @@ void SystemZInstrInfo::expandZExtPseudo(
   MI->eraseFromParent();
 }
 
+void SystemZInstrInfo::expandLoadStackGuard(MachineInstr *MI) const {
+  MachineBasicBlock *MBB = MI->getParent();
+  MachineFunction &MF = *MBB->getParent();
+  const unsigned Reg = MI->getOperand(0).getReg();
+
+  // Conveniently, all 4 instructions are cloned from LOAD_STACK_GUARD,
+  // so they already have operand 0 set to reg.
+
+  // ear <reg>, %a0
+  MachineInstr *Ear1MI = MF.CloneMachineInstr(MI);
+  MBB->insert(MI, Ear1MI);
+  Ear1MI->setDesc(get(SystemZ::EAR));
+  MachineInstrBuilder(MF, Ear1MI).addImm(0);
+
+  // sllg <reg>, <reg>, 32
+  MachineInstr *SllgMI = MF.CloneMachineInstr(MI);
+  MBB->insert(MI, SllgMI);
+  SllgMI->setDesc(get(SystemZ::SLLG));
+  MachineInstrBuilder(MF, SllgMI).addReg(Reg).addReg(0).addImm(32);
+
+  // ear <reg>, %a1
+  MachineInstr *Ear2MI = MF.CloneMachineInstr(MI);
+  MBB->insert(MI, Ear2MI);
+  Ear2MI->setDesc(get(SystemZ::EAR));
+  MachineInstrBuilder(MF, Ear2MI).addImm(1);
+
+  // lg <reg>, 40(<reg>)
+  MI->setDesc(get(SystemZ::LG));
+  MachineInstrBuilder(MF, MI).addReg(Reg).addImm(40).addReg(0);
+}
+
 // Emit a zero-extending move from 32-bit GPR SrcReg to 32-bit GPR
 // DestReg before MBBI in MBB.  Use LowLowOpcode when both DestReg and SrcReg
 // are low registers, otherwise use RISB[LH]G.  Size is the number of bits
@@ -1100,6 +1131,10 @@ SystemZInstrInfo::expandPostRAPseudo(Mac
     splitAdjDynAlloc(MI);
     return true;
 
+  case TargetOpcode::LOAD_STACK_GUARD:
+    expandLoadStackGuard(MI);
+    return true;
+
   default:
     return false;
   }

Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.h?rev=267340&r1=267339&r2=267340&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.h (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.h Sun Apr 24 08:57:49 2016
@@ -141,6 +141,7 @@ class SystemZInstrInfo : public SystemZG
                        unsigned HighOpcode) const;
   void expandZExtPseudo(MachineInstr *MI, unsigned LowOpcode,
                         unsigned Size) const;
+  void expandLoadStackGuard(MachineInstr *MI) const;
   void emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
                      DebugLoc DL, unsigned DestReg, unsigned SrcReg,
                      unsigned LowLowOpcode, unsigned Size, bool KillSrc) const;

Modified: llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.h?rev=267340&r1=267339&r2=267340&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.h (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.h Sun Apr 24 08:57:49 2016
@@ -33,6 +33,15 @@ struct SystemZRegisterInfo : public Syst
 public:
   SystemZRegisterInfo();
 
+  /// getPointerRegClass - Return the register class to use to hold pointers.
+  /// This is currently only used by LOAD_STACK_GUARD, which requires a non-%r0
+  /// register, hence ADDR64.
+  const TargetRegisterClass *
+  getPointerRegClass(const MachineFunction &MF,
+                     unsigned Kind=0) const override {
+    return &SystemZ::ADDR64BitRegClass;
+  }
+
   // Override TargetRegisterInfo.h.
   bool requiresRegisterScavenging(const MachineFunction &MF) const override {
     return true;

Added: llvm/trunk/test/CodeGen/SystemZ/stack-guard.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/stack-guard.ll?rev=267340&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/stack-guard.ll (added)
+++ llvm/trunk/test/CodeGen/SystemZ/stack-guard.ll Sun Apr 24 08:57:49 2016
@@ -0,0 +1,35 @@
+; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+
+; CHECK-LABEL: @test_stack_guard
+; CHECK: ear [[REG1:%r[1-9][0-9]?]], %a0
+; CHECK: sllg [[REG1]], [[REG1]], 32
+; CHECK: ear [[REG1]], %a1
+; CHECK: lg [[REG1]], 40([[REG1]])
+; CHECK: stg [[REG1]], {{[0-9]*}}(%r15)
+; CHECK: brasl %r14, foo3 at PLT
+; CHECK: ear [[REG2:%r[1-9][0-9]?]], %a0
+; CHECK: sllg [[REG2]], [[REG2]], 32
+; CHECK: ear [[REG2]], %a1
+; CHECK: lg [[REG2]], 40([[REG2]])
+; CHECK: sg [[REG2]], {{[0-9]*}}(%r15)
+
+define i32 @test_stack_guard() #0 {
+entry:
+  %a1 = alloca [256 x i32], align 4
+  %0 = bitcast [256 x i32]* %a1 to i8*
+  call void @llvm.lifetime.start(i64 1024, i8* %0)
+  %arraydecay = getelementptr inbounds [256 x i32], [256 x i32]* %a1, i64 0, i64 0
+  call void @foo3(i32* %arraydecay)
+  call void @llvm.lifetime.end(i64 1024, i8* %0)
+  ret i32 0
+}
+
+; Function Attrs: nounwind
+declare void @llvm.lifetime.start(i64, i8* nocapture)
+
+declare void @foo3(i32*)
+
+; Function Attrs: nounwind
+declare void @llvm.lifetime.end(i64, i8* nocapture)
+
+attributes #0 = { sspstrong }




More information about the llvm-commits mailing list