fix materialization of one bit constants and global values which are accessed through
authorReed Kotler <rkotler@mips.com>
Thu, 7 Aug 2014 22:09:01 +0000 (22:09 +0000)
committerReed Kotler <rkotler@mips.com>
Thu, 7 Aug 2014 22:09:01 +0000 (22:09 +0000)
a base GOT entry.

Summary:
get tip of tree mips fast-isel to pass test-suite

Two bugs were fixed:

1) one bit booleans were treated as 1 bit signed integers and so the literal '1' could become sign extended.
2) mips uses got for pic but in certain cases, as with string constants for example, many items can be referenced from the same got entry and this case was not handled properly.

Test Plan: test-suite

Reviewers: dsanders

Reviewed By: dsanders

Subscribers: mcrosier

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215155 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsFastISel.cpp
test/CodeGen/Mips/Fast-ISel/loadstrconst.ll [new file with mode: 0644]

index af4c4ab69e36eccbd6a6753bbe03b3999ac70618..6c053342b7aa790430d4c5fa71ba3f175a521611 100644 (file)
@@ -110,7 +110,7 @@ private:
   }
 
   MachineInstrBuilder EmitInstLoad(unsigned Opc, unsigned DstReg,
-                                      unsigned MemReg, int64_t MemOffset) {
+                                   unsigned MemReg, int64_t MemOffset) {
     return EmitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset);
   }
 
@@ -353,15 +353,23 @@ unsigned MipsFastISel::MaterializeGV(const GlobalValue *GV, MVT VT) {
     return 0;
   EmitInst(Mips::LW, DestReg).addReg(MFI->getGlobalBaseReg()).addGlobalAddress(
       GV, 0, MipsII::MO_GOT);
+  if ((GV->hasInternalLinkage() ||
+       (GV->hasLocalLinkage() && !isa<Function>(GV)))) {
+    unsigned TempReg = createResultReg(RC);
+    EmitInst(Mips::ADDiu, TempReg).addReg(DestReg).addGlobalAddress(
+        GV, 0, MipsII::MO_ABS_LO);
+    DestReg = TempReg;
+  }
   return DestReg;
 }
+
 unsigned MipsFastISel::MaterializeInt(const Constant *C, MVT VT) {
   if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
     return 0;
   const TargetRegisterClass *RC = &Mips::GPR32RegClass;
   const ConstantInt *CI = cast<ConstantInt>(C);
   int64_t Imm;
-  if (CI->isNegative())
+  if ((VT != MVT::i1) && CI->isNegative())
     Imm = CI->getSExtValue();
   else
     Imm = CI->getZExtValue();
diff --git a/test/CodeGen/Mips/Fast-ISel/loadstrconst.ll b/test/CodeGen/Mips/Fast-ISel/loadstrconst.ll
new file mode 100644 (file)
index 0000000..b32e857
--- /dev/null
@@ -0,0 +1,19 @@
+; RUN: llc -march=mipsel -relocation-model=pic -O0 -mips-fast-isel -fast-isel-abort -mcpu=mips32r2 \
+; RUN:     < %s | FileCheck %s
+
+@.str = private unnamed_addr constant [6 x i8] c"hello\00", align 1
+@s = common global i8* null, align 4
+
+; Function Attrs: nounwind
+define void @foo() #0 {
+entry:
+  store i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), i8** @s, align 4
+  ret void
+; CHECK:        .ent    foo
+; CHECK:        lw      $[[REG1:[0-9]+]], %got($.str)(${{[0-9]+}})
+; CHECK:        addiu   ${{[0-9]+}}, $[[REG1]], %lo($.str)
+
+}
+
+attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+