================
@@ -1808,15 +1782,101 @@ bool SystemZInstrInfo::expandPostRAPseudo(MachineInstr 
&MI) const {
     splitAdjDynAlloc(MI);
     return true;
 
-  case TargetOpcode::LOAD_STACK_GUARD:
-    expandLoadStackGuard(&MI);
+  case SystemZ::MOVE_SG:
+    expandStackGuardPseudo(MI, SystemZ::MVC);
+    return true;
+
+  case SystemZ::COMPARE_SG:
+    expandStackGuardPseudo(MI, SystemZ::CLC);
     return true;
 
   default:
     return false;
   }
 }
 
+namespace {
+Register scavengeAddrReg(MachineInstr &MI, MachineBasicBlock *MBB) {
+  // create fresh RegScavanger instance.
+  RegScavenger RS;
+  // initialize RegScavenger to correct location
+  RS.enterBasicBlockEnd(*MBB);
+  RS.backward(MI);
+
+  // Attempt to find a free register.
+  Register Scratch = RS.FindUnusedReg(&SystemZ::ADDR64BitRegClass);
+  // If not found, scavenge one, i.e. evict something to a stack spill slot.
+  if (!Scratch) {
+    Scratch =
+        RS.scavengeRegisterBackwards(SystemZ::ADDR64BitRegClass,
+                                     MI,   // Scavenge back to this position.
+                                     true, // Scope must include MI.
+                                     0,
+                                     true // Spills are allowed.
+        );
+  }
+  return Scratch;
+}
+
+// Check MI (which should be either MOVE_SG or COMPARE_SG)
+// to see if the early-clobber flag on the def reg was honored. If so,
+// return that register. If not, scavenge a new register and return that.
+// This is a workaround for https://github.com/llvm/llvm-project/issues/172511
+// and should be removed once that issue is resolved.
+Register chooseAddrReg(MachineInstr &MI, MachineBasicBlock *MBB) {
+  Register DefReg = MI.getOperand(0).getReg();
+  Register OpReg = MI.getOperand(1).getReg();
+  // if we can use DefReg, return it
+  if (DefReg != OpReg)
+    return DefReg;
+  // otherwise, scavenge
+  return scavengeAddrReg(MI, MBB);
+}
+} // namespace
+
+// Emit the stack guard address load, depending on guard type.
+// Return the register the stack guard address was loaded into.
+unsigned SystemZInstrInfo::emitLoadStackGuardAddress(MachineInstr &MI,
+                                                     Register AddrReg) const {
+  MachineBasicBlock &MBB = *(MI.getParent());
+  const MachineFunction &MF = *(MBB.getParent());
+  const auto DL = MI.getDebugLoc();
+
+  const Module *M = MF.getFunction().getParent();
+  StringRef GuardType = M->getStackProtectorGuard();
+
+  if (GuardType.empty() || (GuardType == "tls")) {
+    // emit a load of the TLS stack guard's address
+    BuildMI(MBB, MI, DL, get(SystemZ::LOAD_TSGA), AddrReg);
+    // return the appropriate stack guard offset (40 in the tls case).
+    return 40;
+  }
+  if (GuardType == "global") {
+    // emit a load of the global stack guard's address
+    BuildMI(MBB, MI, DL, get(SystemZ::LOAD_GSGA), AddrReg);
+    // return the appropriate stack guard offset (0 in the global case).
+    return 0;
+  }
+
+  llvm_unreachable((Twine("Unknown stack protector type \"") + GuardType + 
"\"")
+                       .str()
+                       .c_str());
+}
+
+void SystemZInstrInfo::expandStackGuardPseudo(MachineInstr &MI,
+                                              unsigned Opcode) const {
+  MachineBasicBlock *MBB = MI.getParent();
+  Register AddrReg = chooseAddrReg(MI, MBB);
+  unsigned Offset = emitLoadStackGuardAddress(MI, AddrReg);
----------------
uweigand wrote:

I think the above two function calls could be inlined here?   The scavenger 
code might still stay in a separate function as it will be deleted later on 
anyway.

https://github.com/llvm/llvm-project/pull/169317
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to