[Subzero][MIPS32] Account for variable alloca alignment bytes in addProlog

R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/2425673002 .

Patch from Sagar Thakur <sagar.thakur@imgtec.com>.
diff --git a/src/IceInstMIPS32.h b/src/IceInstMIPS32.h
index 2e367e9..f479316 100644
--- a/src/IceInstMIPS32.h
+++ b/src/IceInstMIPS32.h
@@ -1054,6 +1054,8 @@
     }
   }
 
+  uint32_t getImmediateValue() const { return Imm; }
+
   static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
 
 private:
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp
index 858d2b6..69080e7 100644
--- a/src/IceTargetLoweringMIPS32.cpp
+++ b/src/IceTargetLoweringMIPS32.cpp
@@ -1485,11 +1485,9 @@
   if (!NeedsStackAlignment) {
     SpillAreaSizeBytes += MaxOutArgsSizeBytes * (VariableAllocaUsed ? 0 : 1);
   } else {
-    uint32_t StackOffset = PreservedRegsSizeBytes;
-    uint32_t StackSize = applyStackAlignment(StackOffset + SpillAreaSizeBytes);
-    if (!VariableAllocaUsed)
-      StackSize = applyStackAlignment(StackSize + MaxOutArgsSizeBytes);
-    SpillAreaSizeBytes = StackSize - StackOffset;
+    SpillAreaSizeBytes = applyStackAlignment(
+        SpillAreaSizeBytes +
+        (VariableAllocaUsed ? VariableAllocaAlignBytes : MaxOutArgsSizeBytes));
   }
 
   // Combine fixed alloca with SpillAreaSize.
@@ -1897,6 +1895,24 @@
       llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset)));
 }
 
+Variable *TargetMIPS32::PostLoweringLegalizer::legalizeImmediate(int32_t Imm) {
+  Variable *Reg = nullptr;
+  if (!((std::numeric_limits<int16_t>::min() <= Imm) &&
+        (Imm <= std::numeric_limits<int16_t>::max()))) {
+    const uint32_t UpperBits = (Imm >> 16) & 0xFFFF;
+    const uint32_t LowerBits = Imm & 0xFFFF;
+    Variable *TReg = Target->makeReg(IceType_i32, Target->getReservedTmpReg());
+    Reg = Target->makeReg(IceType_i32, Target->getReservedTmpReg());
+    if (LowerBits) {
+      Target->_lui(TReg, Target->Ctx->getConstantInt32(UpperBits));
+      Target->_ori(Reg, TReg, LowerBits);
+    } else {
+      Target->_lui(Reg, Target->Ctx->getConstantInt32(UpperBits));
+    }
+  }
+  return Reg;
+}
+
 void TargetMIPS32::postLowerLegalization() {
   Func->dump("Before postLowerLegalization");
   assert(hasComputedFrame());
@@ -1959,6 +1975,14 @@
         }
         continue;
       }
+      if (auto *AddiuInstr = llvm::dyn_cast<InstMIPS32Addiu>(CurInstr)) {
+        if (auto *LegalImm = Legalizer.legalizeImmediate(
+                static_cast<int32_t>(AddiuInstr->getImmediateValue()))) {
+          _addu(Dst, Src0V, LegalImm);
+          CurInstr->setDeleted();
+        }
+        continue;
+      }
     }
   }
 }
@@ -2150,6 +2174,7 @@
     // Non-constant sizes need to be adjusted to the next highest multiple of
     // the required alignment at runtime.
     VariableAllocaUsed = true;
+    VariableAllocaAlignBytes = AlignmentParam;
     Variable *AlignAmount;
     auto *TotalSizeR = legalizeToReg(TotalSize, Legal_Reg);
     auto *T1 = I32Reg();
diff --git a/src/IceTargetLoweringMIPS32.h b/src/IceTargetLoweringMIPS32.h
index 09b981b..283e98c 100644
--- a/src/IceTargetLoweringMIPS32.h
+++ b/src/IceTargetLoweringMIPS32.h
@@ -734,6 +734,9 @@
     /// Mem.Offset is fixed up.
     OperandMIPS32Mem *legalizeMemOperand(OperandMIPS32Mem *Mem);
 
+    /// Legalizes Immediate if larger value overflows range of 16 bits
+    Variable *legalizeImmediate(int32_t Imm);
+
     /// Legalizes Mov if its Source (or Destination) is a spilled Variable, or
     /// if its Source is a Rematerializable variable (this form is used in lieu
     /// of lea, which is not available in MIPS.)
@@ -758,6 +761,7 @@
   uint32_t MaxOutArgsSizeBytes = 0;
   uint32_t TotalStackSizeBytes = 0;
   uint32_t CurrentAllocaOffset = 0;
+  uint32_t VariableAllocaAlignBytes = 0;
   static SmallBitVector TypeToRegisterSet[RCMIPS32_NUM];
   static SmallBitVector TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
   static SmallBitVector RegisterAliases[RegMIPS32::Reg_NUM];
diff --git a/tests_lit/llvm2ice_tests/alloc.ll b/tests_lit/llvm2ice_tests/alloc.ll
index 07cff69..ffb5e48 100644
--- a/tests_lit/llvm2ice_tests/alloc.ll
+++ b/tests_lit/llvm2ice_tests/alloc.ll
@@ -62,9 +62,9 @@
 ; ARM32:       bl {{.*}} R_{{.*}}    f1
 
 ; MIPS32-LABEL: fixed_416_align_16
-; MIPS32-OPT2: addiu sp,sp,-448
+; MIPS32-OPT2: addiu sp,sp,-436
 ; MIPS32-OPT2: addiu a0,sp,16
-; MIPS32-OPTM1: addiu sp,sp,-448
+; MIPS32-OPTM1: addiu sp,sp,-456
 ; MIPS32-OPTM1: addiu [[REG:.*]],sp,16
 ; MIPS32-OPTM1: sw [[REG]],{{.*}}
 ; MIPS32-OPTM1: lw a0,{{.*}}
@@ -93,9 +93,9 @@
 ; ARM32:       bl {{.*}} R_{{.*}}    f1
 
 ; MIPS32-LABEL: fixed_416_align_32
-; MIPS32-OPT2: addiu sp,sp,-448
+; MIPS32-OPT2: addiu sp,sp,-440
 ; MIPS32-OPT2: addiu a0,sp,32
-; MIPS32-OPTM1: addiu sp,sp,-448
+; MIPS32-OPTM1: addiu sp,sp,-456
 ; MIPS32-OPTM1: addiu [[REG:.*]],sp,32
 ; MIPS32-OPTM1: sw [[REG]],{{.*}}
 ; MIPS32-OPTM1: lw a0,{{.*}}
@@ -127,9 +127,9 @@
 ; ARM32:       bl {{.*}} R_{{.*}}    f1
 
 ; MIPS32-LABEL: fixed_351_align_16
-; MIPS32-OPT2: addiu sp,sp,-384
+; MIPS32-OPT2: addiu sp,sp,-372
 ; MIPS32-OPT2: addiu a0,sp,16
-; MIPS32-OPTM1: addiu sp,sp,-384
+; MIPS32-OPTM1: addiu sp,sp,-392
 ; MIPS32-OPTM1: addiu [[REG:.*]],sp,16
 ; MIPS32-OPTM1: sw [[REG]],{{.*}}
 ; MIPS32-OPTM1: lw a0,{{.*}}
@@ -158,9 +158,9 @@
 ; ARM32:       bl {{.*}} R_{{.*}}    f1
 
 ; MIPS32-LABEL: fixed_351_align_32
-; MIPS32-OPT2: addiu sp,sp,-384
+; MIPS32-OPT2: addiu sp,sp,-376
 ; MIPS32-OPT2: addiu a0,sp,32
-; MIPS32-OPTM1: addiu sp,sp,-384
+; MIPS32-OPTM1: addiu sp,sp,-392
 ; MIPS32-OPTM1: addiu [[REG:.*]],sp,32
 ; MIPS32-OPTM1: sw [[REG]],{{.*}}
 ; MIPS32-OPTM1: lw a0,{{.*}}