summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Dardis <simon.dardis@mips.com>2017-12-14 14:55:25 +0000
committerSimon Dardis <simon.dardis@mips.com>2017-12-14 14:55:25 +0000
commite94fdd125fdd7141d5c1ee54d69a7c4dccef07ee (patch)
tree60d9ed68606d42add80b5e27e7b69c801e0025dc
parent33eaf177024e6b3126fa05043e229abf1579fd20 (diff)
downloadbcm5719-llvm-e94fdd125fdd7141d5c1ee54d69a7c4dccef07ee.tar.gz
bcm5719-llvm-e94fdd125fdd7141d5c1ee54d69a7c4dccef07ee.zip
[mips] Add partial support for R6 in the long branch pass
MIPSR6 introduced several new jump instructions and deprecated the use of the 'j' instruction. For microMIPS32R6, 'j' was removed entirely and it only has non delay slot jumps. This patch adds support for MIPSR6 by using some R6 instructions-- 'bc' instead of 'j', 'jic $reg, 0' instead of 'jalr $zero, $reg'-- and modifies the sequences not to use delay slots for R6. Reviewers: atanasyan Reviewed By: atanasyan Subscribers: dschuff, arichardson, llvm-commits Differential Revision: https://reviews.llvm.org/D40786 llvm-svn: 320703
-rw-r--r--llvm/lib/Target/Mips/MipsLongBranch.cpp162
-rw-r--r--llvm/test/CodeGen/Mips/longbranch.ll464
2 files changed, 425 insertions, 201 deletions
diff --git a/llvm/lib/Target/Mips/MipsLongBranch.cpp b/llvm/lib/Target/Mips/MipsLongBranch.cpp
index 9af4f4b1cd4..bbf2050ce1e 100644
--- a/llvm/lib/Target/Mips/MipsLongBranch.cpp
+++ b/llvm/lib/Target/Mips/MipsLongBranch.cpp
@@ -279,12 +279,16 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
LongBrMBB->addSuccessor(BalTgtMBB);
BalTgtMBB->addSuccessor(TgtMBB);
- // We must select between the MIPS32r6/MIPS64r6 BAL (which is a normal
+ // We must select between the MIPS32r6/MIPS64r6 BALC (which is a normal
// instruction) and the pre-MIPS32r6/MIPS64r6 definition (which is an
// pseudo-instruction wrapping BGEZAL).
- unsigned BalOp = Subtarget.hasMips32r6() ? Mips::BAL : Mips::BAL_BR;
+ const unsigned BalOp =
+ Subtarget.hasMips32r6()
+ ? Subtarget.inMicroMipsMode() ? Mips::BALC_MMR6 : Mips::BALC
+ : Mips::BAL_BR;
if (!ABI.IsN64()) {
+ // Pre R6:
// $longbr:
// addiu $sp, $sp, -8
// sw $ra, 0($sp)
@@ -299,6 +303,20 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
// $fallthrough:
//
+ // R6:
+ // $longbr:
+ // addiu $sp, $sp, -8
+ // sw $ra, 0($sp)
+ // lui $at, %hi($tgt - $baltgt)
+ // addiu $at, $at, %lo($tgt - $baltgt)
+ // balc $baltgt
+ // $baltgt:
+ // addu $at, $ra, $at
+ // lw $ra, 0($sp)
+ // addiu $sp, $sp, 8
+ // jic $at, 0
+ // $fallthrough:
+
Pos = LongBrMBB->begin();
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
@@ -307,7 +325,7 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
.addReg(Mips::SP).addImm(0);
// LUi and ADDiu instructions create 32-bit offset of the target basic
- // block from the target of BAL instruction. We cannot use immediate
+ // block from the target of BAL(C) instruction. We cannot use immediate
// value for this offset because it cannot be determined accurately when
// the program has inline assembly statements. We therefore use the
// relocation expressions %hi($tgt-$baltgt) and %lo($tgt-$baltgt) which
@@ -324,12 +342,22 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi), Mips::AT)
.addMBB(TgtMBB).addMBB(BalTgtMBB);
- MIBundleBuilder(*LongBrMBB, Pos)
- .append(BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB))
- .append(BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT)
- .addReg(Mips::AT)
- .addMBB(TgtMBB)
- .addMBB(BalTgtMBB));
+
+ MachineInstrBuilder BalInstr =
+ BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB);
+ MachineInstrBuilder ADDiuInstr =
+ BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT)
+ .addReg(Mips::AT)
+ .addMBB(TgtMBB)
+ .addMBB(BalTgtMBB);
+ if (Subtarget.hasMips32r6()) {
+ LongBrMBB->insert(Pos, ADDiuInstr);
+ LongBrMBB->insert(Pos, BalInstr);
+ } else {
+ LongBrMBB->insert(Pos, BalInstr);
+ LongBrMBB->insert(Pos, ADDiuInstr);
+ LongBrMBB->rbegin()->bundleWithPred();
+ }
Pos = BalTgtMBB->begin();
@@ -337,28 +365,37 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
.addReg(Mips::RA).addReg(Mips::AT);
BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA)
.addReg(Mips::SP).addImm(0);
+ if (Subtarget.isTargetNaCl())
+ // Bundle-align the target of indirect branch JR.
+ TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN);
// In NaCl, modifying the sp is not allowed in branch delay slot.
- if (Subtarget.isTargetNaCl())
+ // For MIPS32R6, we can skip using a delay slot branch.
+ if (Subtarget.isTargetNaCl() || Subtarget.hasMips32r6())
BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
.addReg(Mips::SP).addImm(8);
- if (Subtarget.hasMips32r6())
- BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JALR))
- .addReg(Mips::ZERO).addReg(Mips::AT);
- else
+ if (Subtarget.hasMips32r6()) {
+ const unsigned JICOp =
+ Subtarget.inMicroMipsMode() ? Mips::JIC_MMR6 : Mips::JIC;
+ BuildMI(*BalTgtMBB, Pos, DL, TII->get(JICOp))
+ .addReg(Mips::AT)
+ .addImm(0);
+
+ } else {
BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JR)).addReg(Mips::AT);
- if (Subtarget.isTargetNaCl()) {
- BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NOP));
- // Bundle-align the target of indirect branch JR.
- TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN);
- } else
- BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
- .addReg(Mips::SP).addImm(8);
+ if (Subtarget.isTargetNaCl()) {
+ BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NOP));
+ } else
+ BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
+ .addReg(Mips::SP)
+ .addImm(8);
- BalTgtMBB->rbegin()->bundleWithPred();
+ BalTgtMBB->rbegin()->bundleWithPred();
+ }
} else {
+ // Pre R6:
// $longbr:
// daddiu $sp, $sp, -16
// sd $ra, 0($sp)
@@ -372,7 +409,21 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
// jr64 $at
// daddiu $sp, $sp, 16
// $fallthrough:
- //
+
+ // R6:
+ // $longbr:
+ // daddiu $sp, $sp, -16
+ // sd $ra, 0($sp)
+ // daddiu $at, $zero, %hi($tgt - $baltgt)
+ // dsll $at, $at, 16
+ // daddiu $at, $at, %lo($tgt - $baltgt)
+ // balc $baltgt
+ // $baltgt:
+ // daddu $at, $ra, $at
+ // ld $ra, 0($sp)
+ // daddiu $sp, $sp, 16
+ // jic $at, 0
+ // $fallthrough:
// We assume the branch is within-function, and that offset is within
// +/- 2GB. High 32 bits will therefore always be zero.
@@ -401,13 +452,21 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
.addReg(Mips::AT_64).addImm(16);
- MIBundleBuilder(*LongBrMBB, Pos)
- .append(BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB))
- .append(
- BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64)
- .addReg(Mips::AT_64)
- .addMBB(TgtMBB, MipsII::MO_ABS_LO)
- .addMBB(BalTgtMBB));
+ MachineInstrBuilder BalInstr =
+ BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB);
+ MachineInstrBuilder DADDiuInstr =
+ BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64)
+ .addReg(Mips::AT_64)
+ .addMBB(TgtMBB, MipsII::MO_ABS_LO)
+ .addMBB(BalTgtMBB);
+ if (Subtarget.hasMips32r6()) {
+ LongBrMBB->insert(Pos, DADDiuInstr);
+ LongBrMBB->insert(Pos, BalInstr);
+ } else {
+ LongBrMBB->insert(Pos, BalInstr);
+ LongBrMBB->insert(Pos, DADDiuInstr);
+ LongBrMBB->rbegin()->bundleWithPred();
+ }
Pos = BalTgtMBB->begin();
@@ -416,29 +475,40 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64)
.addReg(Mips::SP_64).addImm(0);
- if (Subtarget.hasMips64r6())
- BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JALR64))
- .addReg(Mips::ZERO_64).addReg(Mips::AT_64);
- else
+ if (Subtarget.hasMips64r6()) {
+ BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
+ .addReg(Mips::SP_64)
+ .addImm(16);
+ BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JIC64))
+ .addReg(Mips::AT_64)
+ .addImm(0);
+ } else {
BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JR64)).addReg(Mips::AT_64);
-
- BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
- .addReg(Mips::SP_64).addImm(16);
- BalTgtMBB->rbegin()->bundleWithPred();
+ BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
+ .addReg(Mips::SP_64)
+ .addImm(16);
+ BalTgtMBB->rbegin()->bundleWithPred();
+ }
}
assert(LongBrMBB->size() + BalTgtMBB->size() == LongBranchSeqSize);
} else {
- // $longbr:
- // j $tgt
- // nop
+ // Pre R6: R6:
+ // $longbr: $longbr:
+ // j $tgt bc $tgt
+ // nop $fallthrough
// $fallthrough:
//
Pos = LongBrMBB->begin();
LongBrMBB->addSuccessor(TgtMBB);
- MIBundleBuilder(*LongBrMBB, Pos)
- .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB))
- .append(BuildMI(*MF, DL, TII->get(Mips::NOP)));
+ if (Subtarget.hasMips32r6())
+ BuildMI(*LongBrMBB, Pos, DL,
+ TII->get(Subtarget.inMicroMipsMode() ? Mips::BC_MMR6 : Mips::BC))
+ .addMBB(TgtMBB);
+ else
+ MIBundleBuilder(*LongBrMBB, Pos)
+ .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB))
+ .append(BuildMI(*MF, DL, TII->get(Mips::NOP)));
assert(LongBrMBB->size() == LongBranchSeqSize);
}
@@ -474,8 +544,8 @@ bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) {
IsPIC = TM.isPositionIndependent();
ABI = static_cast<const MipsTargetMachine &>(TM).getABI();
- LongBranchSeqSize =
- !IsPIC ? 2 : (ABI.IsN64() ? 10 : (!STI.isTargetNaCl() ? 9 : 10));
+ LongBranchSeqSize = IsPIC ? ((ABI.IsN64() || STI.isTargetNaCl()) ? 10 : 9)
+ : (STI.hasMips32r6() ? 1 : 2);
if (STI.inMips16Mode() || !STI.enableLongBranchPass())
return false;
diff --git a/llvm/test/CodeGen/Mips/longbranch.ll b/llvm/test/CodeGen/Mips/longbranch.ll
index 11bc6d39031..69eb18978e5 100644
--- a/llvm/test/CodeGen/Mips/longbranch.ll
+++ b/llvm/test/CodeGen/Mips/longbranch.ll
@@ -1,16 +1,35 @@
-; RUN: llc -march=mipsel -relocation-model=pic < %s | FileCheck %s
-; RUN: llc -march=mipsel -force-mips-long-branch -O3 -relocation-model=pic < %s \
-; RUN: | FileCheck %s -check-prefix=O32
-; RUN: llc -march=mipsel -mcpu=mips32r6 -force-mips-long-branch -O3 \
-; RUN: -relocation-model=pic -asm-show-inst < %s | FileCheck %s -check-prefix=O32-R6
-; RUN: llc -march=mips64el -mcpu=mips4 -target-abi=n64 -force-mips-long-branch -O3 -relocation-model=pic \
-; RUN: < %s | FileCheck %s -check-prefix=N64
-; RUN: llc -march=mips64el -mcpu=mips64 -target-abi=n64 -force-mips-long-branch -O3 -relocation-model=pic \
-; RUN: < %s | FileCheck %s -check-prefix=N64
-; RUN: llc -march=mips64el -mcpu=mips64r6 -target-abi=n64 -force-mips-long-branch -O3 \
-; RUN: -relocation-model=pic -asm-show-inst < %s | FileCheck %s -check-prefix=N64-R6
-; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=micromips \
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; Except for the NACL version which isn't parsed by update_llc_test_checks.py
+; RUN: llc -mtriple=mipsel-unknown-linux-gnu -O3 -relocation-model=pic < %s \
+; RUN: | FileCheck %s -check-prefix=NOLONGBRANCH
+
+; RUN: llc -mtriple=mipsel-unknown-linux-gnu -force-mips-long-branch -O3 -relocation-model=pic < %s \
+; RUN: | FileCheck %s -check-prefix=O32-PIC
+; RUN: llc -mtriple=mipsel-unknown-linux-gnu -force-mips-long-branch -O3 -relocation-model=static < %s \
+; RUN: | FileCheck %s -check-prefix=O32-STATIC
+; RUN: llc -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r6 -force-mips-long-branch -O3 \
+; RUN: -relocation-model=pic < %s | FileCheck %s -check-prefix=O32-R6-PIC
+; RUN: llc -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r6 -force-mips-long-branch -O3 \
+; RUN: -relocation-model=static < %s | FileCheck %s -check-prefix=O32-R6-STATIC
+
+; RUN: llc -mtriple=mips64el-unknown-linux-gnu -mcpu=mips4 -target-abi=n64 -force-mips-long-branch -O3 -relocation-model=pic \
+; RUN: < %s | FileCheck %s -check-prefix=MIPS4
+; RUN: llc -mtriple=mips64el-unknown-linux-gnu -mcpu=mips64 -target-abi=n64 -force-mips-long-branch -O3 -relocation-model=pic \
+; RUN: < %s | FileCheck %s -check-prefix=MIPS64
+; RUN: llc -mtriple=mips64el-unknown-linux-gnu -mcpu=mips64r6 -target-abi=n64 -force-mips-long-branch -O3 \
+; RUN: -relocation-model=pic < %s | FileCheck %s -check-prefix=N64-R6
+
+; RUN: llc -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r2 -mattr=micromips \
; RUN: -force-mips-long-branch -O3 -relocation-model=pic < %s | FileCheck %s -check-prefix=MICROMIPS
+; RUN: llc -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r2 -mattr=micromips \
+; RUN: -force-mips-long-branch -O3 -relocation-model=static < %s | FileCheck %s -check-prefix=MICROMIPSSTATIC
+
+; RUN: llc -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r6 -mattr=micromips \
+; RUN: -force-mips-long-branch -O3 -relocation-model=static < %s | FileCheck %s -check-prefix=MICROMIPSR6STATIC
+; RUN: llc -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r6 -mattr=micromips \
+; RUN: -force-mips-long-branch -O3 -relocation-model=pic < %s | FileCheck %s -check-prefix=MICROMIPSR6PIC
+
+
; RUN: llc -mtriple=mipsel-none-nacl -force-mips-long-branch -O3 -relocation-model=pic < %s \
; RUN: | FileCheck %s -check-prefix=NACL
@@ -18,6 +37,284 @@
@x = external global i32
define void @test1(i32 signext %s) {
+; NOLONGBRANCH-LABEL: test1:
+; NOLONGBRANCH: # %bb.0: # %entry
+; NOLONGBRANCH-NEXT: lui $2, %hi(_gp_disp)
+; NOLONGBRANCH-NEXT: addiu $2, $2, %lo(_gp_disp)
+; NOLONGBRANCH-NEXT: beqz $4, $BB0_2
+; NOLONGBRANCH-NEXT: addu $2, $2, $25
+; NOLONGBRANCH-NEXT: # %bb.1: # %then
+; NOLONGBRANCH-NEXT: lw $1, %got(x)($2)
+; NOLONGBRANCH-NEXT: addiu $2, $zero, 1
+; NOLONGBRANCH-NEXT: sw $2, 0($1)
+; NOLONGBRANCH-NEXT: $BB0_2: # %end
+; NOLONGBRANCH-NEXT: jr $ra
+; NOLONGBRANCH-NEXT: nop
+;
+; O32-PIC-LABEL: test1:
+; O32-PIC: # %bb.0: # %entry
+; O32-PIC-NEXT: lui $2, %hi(_gp_disp)
+; O32-PIC-NEXT: addiu $2, $2, %lo(_gp_disp)
+; O32-PIC-NEXT: bnez $4, $BB0_3
+; O32-PIC-NEXT: addu $2, $2, $25
+; O32-PIC-NEXT: # %bb.1: # %entry
+; O32-PIC-NEXT: addiu $sp, $sp, -8
+; O32-PIC-NEXT: sw $ra, 0($sp)
+; O32-PIC-NEXT: lui $1, %hi(($BB0_4)-($BB0_2))
+; O32-PIC-NEXT: bal $BB0_2
+; O32-PIC-NEXT: addiu $1, $1, %lo(($BB0_4)-($BB0_2))
+; O32-PIC-NEXT: $BB0_2: # %entry
+; O32-PIC-NEXT: addu $1, $ra, $1
+; O32-PIC-NEXT: lw $ra, 0($sp)
+; O32-PIC-NEXT: jr $1
+; O32-PIC-NEXT: addiu $sp, $sp, 8
+; O32-PIC-NEXT: $BB0_3: # %then
+; O32-PIC-NEXT: lw $1, %got(x)($2)
+; O32-PIC-NEXT: addiu $2, $zero, 1
+; O32-PIC-NEXT: sw $2, 0($1)
+; O32-PIC-NEXT: $BB0_4: # %end
+; O32-PIC-NEXT: jr $ra
+; O32-PIC-NEXT: nop
+;
+; O32-STATIC-LABEL: test1:
+; O32-STATIC: # %bb.0: # %entry
+; O32-STATIC-NEXT: bnez $4, $BB0_2
+; O32-STATIC-NEXT: nop
+; O32-STATIC-NEXT: # %bb.1: # %entry
+; O32-STATIC-NEXT: j $BB0_3
+; O32-STATIC-NEXT: nop
+; O32-STATIC-NEXT: $BB0_2: # %then
+; O32-STATIC-NEXT: lui $1, %hi(x)
+; O32-STATIC-NEXT: addiu $2, $zero, 1
+; O32-STATIC-NEXT: sw $2, %lo(x)($1)
+; O32-STATIC-NEXT: $BB0_3: # %end
+; O32-STATIC-NEXT: jr $ra
+; O32-STATIC-NEXT: nop
+;
+; O32-R6-PIC-LABEL: test1:
+; O32-R6-PIC: # %bb.0: # %entry
+; O32-R6-PIC-NEXT: lui $2, %hi(_gp_disp)
+; O32-R6-PIC-NEXT: addiu $2, $2, %lo(_gp_disp)
+; O32-R6-PIC-NEXT: bnez $4, $BB0_3
+; O32-R6-PIC-NEXT: addu $2, $2, $25
+; O32-R6-PIC-NEXT: # %bb.1: # %entry
+; O32-R6-PIC-NEXT: addiu $sp, $sp, -8
+; O32-R6-PIC-NEXT: sw $ra, 0($sp)
+; O32-R6-PIC-NEXT: lui $1, %hi(($BB0_4)-($BB0_2))
+; O32-R6-PIC-NEXT: addiu $1, $1, %lo(($BB0_4)-($BB0_2))
+; O32-R6-PIC-NEXT: balc $BB0_2
+; O32-R6-PIC-NEXT: $BB0_2: # %entry
+; O32-R6-PIC-NEXT: addu $1, $ra, $1
+; O32-R6-PIC-NEXT: lw $ra, 0($sp)
+; O32-R6-PIC-NEXT: addiu $sp, $sp, 8
+; O32-R6-PIC-NEXT: jrc $1
+; O32-R6-PIC-NEXT: $BB0_3: # %then
+; O32-R6-PIC-NEXT: lw $1, %got(x)($2)
+; O32-R6-PIC-NEXT: addiu $2, $zero, 1
+; O32-R6-PIC-NEXT: sw $2, 0($1)
+; O32-R6-PIC-NEXT: $BB0_4: # %end
+; O32-R6-PIC-NEXT: jrc $ra
+;
+; O32-R6-STATIC-LABEL: test1:
+; O32-R6-STATIC: # %bb.0: # %entry
+; O32-R6-STATIC-NEXT: bnezc $4, $BB0_2
+; O32-R6-STATIC-NEXT: nop
+; O32-R6-STATIC-NEXT: # %bb.1: # %entry
+; O32-R6-STATIC-NEXT: bc $BB0_3
+; O32-R6-STATIC-NEXT: $BB0_2: # %then
+; O32-R6-STATIC-NEXT: lui $1, %hi(x)
+; O32-R6-STATIC-NEXT: addiu $2, $zero, 1
+; O32-R6-STATIC-NEXT: sw $2, %lo(x)($1)
+; O32-R6-STATIC-NEXT: $BB0_3: # %end
+; O32-R6-STATIC-NEXT: jrc $ra
+;
+; MIPS4-LABEL: test1:
+; MIPS4: # %bb.0: # %entry
+; MIPS4-NEXT: lui $1, %hi(%neg(%gp_rel(test1)))
+; MIPS4-NEXT: bnez $4, .LBB0_3
+; MIPS4-NEXT: daddu $2, $1, $25
+; MIPS4-NEXT: # %bb.1: # %entry
+; MIPS4-NEXT: daddiu $sp, $sp, -16
+; MIPS4-NEXT: sd $ra, 0($sp)
+; MIPS4-NEXT: daddiu $1, $zero, %hi(.LBB0_4-.LBB0_2)
+; MIPS4-NEXT: dsll $1, $1, 16
+; MIPS4-NEXT: bal .LBB0_2
+; MIPS4-NEXT: daddiu $1, $1, %lo(.LBB0_4-.LBB0_2)
+; MIPS4-NEXT: .LBB0_2: # %entry
+; MIPS4-NEXT: daddu $1, $ra, $1
+; MIPS4-NEXT: ld $ra, 0($sp)
+; MIPS4-NEXT: jr $1
+; MIPS4-NEXT: daddiu $sp, $sp, 16
+; MIPS4-NEXT: .LBB0_3: # %then
+; MIPS4-NEXT: daddiu $1, $2, %lo(%neg(%gp_rel(test1)))
+; MIPS4-NEXT: addiu $2, $zero, 1
+; MIPS4-NEXT: ld $1, %got_disp(x)($1)
+; MIPS4-NEXT: sw $2, 0($1)
+; MIPS4-NEXT: .LBB0_4: # %end
+; MIPS4-NEXT: jr $ra
+; MIPS4-NEXT: nop
+;
+; MIPS64-LABEL: test1:
+; MIPS64: # %bb.0: # %entry
+; MIPS64-NEXT: lui $1, %hi(%neg(%gp_rel(test1)))
+; MIPS64-NEXT: bnez $4, .LBB0_3
+; MIPS64-NEXT: daddu $2, $1, $25
+; MIPS64-NEXT: # %bb.1: # %entry
+; MIPS64-NEXT: daddiu $sp, $sp, -16
+; MIPS64-NEXT: sd $ra, 0($sp)
+; MIPS64-NEXT: daddiu $1, $zero, %hi(.LBB0_4-.LBB0_2)
+; MIPS64-NEXT: dsll $1, $1, 16
+; MIPS64-NEXT: bal .LBB0_2
+; MIPS64-NEXT: daddiu $1, $1, %lo(.LBB0_4-.LBB0_2)
+; MIPS64-NEXT: .LBB0_2: # %entry
+; MIPS64-NEXT: daddu $1, $ra, $1
+; MIPS64-NEXT: ld $ra, 0($sp)
+; MIPS64-NEXT: jr $1
+; MIPS64-NEXT: daddiu $sp, $sp, 16
+; MIPS64-NEXT: .LBB0_3: # %then
+; MIPS64-NEXT: daddiu $1, $2, %lo(%neg(%gp_rel(test1)))
+; MIPS64-NEXT: addiu $2, $zero, 1
+; MIPS64-NEXT: ld $1, %got_disp(x)($1)
+; MIPS64-NEXT: sw $2, 0($1)
+; MIPS64-NEXT: .LBB0_4: # %end
+; MIPS64-NEXT: jr $ra
+; MIPS64-NEXT: nop
+;
+; N64-R6-LABEL: test1:
+; N64-R6: # %bb.0: # %entry
+; N64-R6-NEXT: lui $1, %hi(%neg(%gp_rel(test1)))
+; N64-R6-NEXT: bnez $4, .LBB0_3
+; N64-R6-NEXT: daddu $2, $1, $25
+; N64-R6-NEXT: # %bb.1: # %entry
+; N64-R6-NEXT: daddiu $sp, $sp, -16
+; N64-R6-NEXT: sd $ra, 0($sp)
+; N64-R6-NEXT: daddiu $1, $zero, %hi(.LBB0_4-.LBB0_2)
+; N64-R6-NEXT: dsll $1, $1, 16
+; N64-R6-NEXT: daddiu $1, $1, %lo(.LBB0_4-.LBB0_2)
+; N64-R6-NEXT: balc .LBB0_2
+; N64-R6-NEXT: .LBB0_2: # %entry
+; N64-R6-NEXT: daddu $1, $ra, $1
+; N64-R6-NEXT: ld $ra, 0($sp)
+; N64-R6-NEXT: daddiu $sp, $sp, 16
+; N64-R6-NEXT: jrc $1
+; N64-R6-NEXT: .LBB0_3: # %then
+; N64-R6-NEXT: daddiu $1, $2, %lo(%neg(%gp_rel(test1)))
+; N64-R6-NEXT: addiu $2, $zero, 1
+; N64-R6-NEXT: ld $1, %got_disp(x)($1)
+; N64-R6-NEXT: sw $2, 0($1)
+; N64-R6-NEXT: .LBB0_4: # %end
+; N64-R6-NEXT: jrc $ra
+;
+; MICROMIPS-LABEL: test1:
+; MICROMIPS: # %bb.0: # %entry
+; MICROMIPS-NEXT: lui $2, %hi(_gp_disp)
+; MICROMIPS-NEXT: addiu $2, $2, %lo(_gp_disp)
+; MICROMIPS-NEXT: bnez $4, $BB0_3
+; MICROMIPS-NEXT: addu $2, $2, $25
+; MICROMIPS-NEXT: # %bb.1: # %entry
+; MICROMIPS-NEXT: addiu $sp, $sp, -8
+; MICROMIPS-NEXT: sw $ra, 0($sp)
+; MICROMIPS-NEXT: lui $1, %hi(($BB0_4)-($BB0_2))
+; MICROMIPS-NEXT: bal $BB0_2
+; MICROMIPS-NEXT: addiu $1, $1, %lo(($BB0_4)-($BB0_2))
+; MICROMIPS-NEXT: $BB0_2: # %entry
+; MICROMIPS-NEXT: addu $1, $ra, $1
+; MICROMIPS-NEXT: lw $ra, 0($sp)
+; MICROMIPS-NEXT: jr $1
+; MICROMIPS-NEXT: addiu $sp, $sp, 8
+; MICROMIPS-NEXT: $BB0_3: # %then
+; MICROMIPS-NEXT: lw $2, %got(x)($2)
+; MICROMIPS-NEXT: li16 $3, 1
+; MICROMIPS-NEXT: sw16 $3, 0($2)
+; MICROMIPS-NEXT: $BB0_4: # %end
+; MICROMIPS-NEXT: jrc $ra
+;
+; MICROMIPSSTATIC-LABEL: test1:
+; MICROMIPSSTATIC: # %bb.0: # %entry
+; MICROMIPSSTATIC-NEXT: bnezc $4, $BB0_2
+; MICROMIPSSTATIC-NEXT: # %bb.1: # %entry
+; MICROMIPSSTATIC-NEXT: j $BB0_4
+; MICROMIPSSTATIC-NEXT: nop
+; MICROMIPSSTATIC-NEXT: $BB0_2: # %entry
+; MICROMIPSSTATIC-NEXT: j $BB0_3
+; MICROMIPSSTATIC-NEXT: nop
+; MICROMIPSSTATIC-NEXT: $BB0_3: # %then
+; MICROMIPSSTATIC-NEXT: lui $1, %hi(x)
+; MICROMIPSSTATIC-NEXT: li16 $2, 1
+; MICROMIPSSTATIC-NEXT: sw $2, %lo(x)($1)
+; MICROMIPSSTATIC-NEXT: $BB0_4: # %end
+; MICROMIPSSTATIC-NEXT: jrc $ra
+;
+; MICROMIPSR6STATIC-LABEL: test1:
+; MICROMIPSR6STATIC: # %bb.0: # %entry
+; MICROMIPSR6STATIC-NEXT: bnezc $4, $BB0_2
+; MICROMIPSR6STATIC-NEXT: # %bb.1: # %entry
+; MICROMIPSR6STATIC-NEXT: bc $BB0_4
+; MICROMIPSR6STATIC-NEXT: $BB0_2: # %entry
+; MICROMIPSR6STATIC-NEXT: bc $BB0_3
+; MICROMIPSR6STATIC-NEXT: $BB0_3: # %then
+; MICROMIPSR6STATIC-NEXT: lui $1, %hi(x)
+; MICROMIPSR6STATIC-NEXT: li16 $2, 1
+; MICROMIPSR6STATIC-NEXT: sw $2, %lo(x)($1)
+; MICROMIPSR6STATIC-NEXT: $BB0_4: # %end
+; MICROMIPSR6STATIC-NEXT: jrc $ra
+;
+; MICROMIPSR6PIC-LABEL: test1:
+; MICROMIPSR6PIC: # %bb.0: # %entry
+; MICROMIPSR6PIC-NEXT: lui $2, %hi(_gp_disp)
+; MICROMIPSR6PIC-NEXT: addiu $2, $2, %lo(_gp_disp)
+; MICROMIPSR6PIC-NEXT: addu $2, $2, $25
+; MICROMIPSR6PIC-NEXT: bnezc $4, $BB0_3
+; MICROMIPSR6PIC-NEXT: # %bb.1: # %entry
+; MICROMIPSR6PIC-NEXT: addiu $sp, $sp, -8
+; MICROMIPSR6PIC-NEXT: sw $ra, 0($sp)
+; MICROMIPSR6PIC-NEXT: lui $1, %hi(($BB0_4)-($BB0_2))
+; MICROMIPSR6PIC-NEXT: addiu $1, $1, %lo(($BB0_4)-($BB0_2))
+; MICROMIPSR6PIC-NEXT: balc $BB0_2
+; MICROMIPSR6PIC-NEXT: $BB0_2: # %entry
+; MICROMIPSR6PIC-NEXT: addu $1, $ra, $1
+; MICROMIPSR6PIC-NEXT: lw $ra, 0($sp)
+; MICROMIPSR6PIC-NEXT: addiu $sp, $sp, 8
+; MICROMIPSR6PIC-NEXT: jic $1, 0
+; MICROMIPSR6PIC-NEXT: $BB0_3: # %then
+; MICROMIPSR6PIC-NEXT: lw $2, %got(x)($2)
+; MICROMIPSR6PIC-NEXT: li16 $3, 1
+; MICROMIPSR6PIC-NEXT: sw16 $3, 0($2)
+; MICROMIPSR6PIC-NEXT: $BB0_4: # %end
+; MICROMIPSR6PIC-NEXT: jrc $ra
+
+; NACL-LABEL: test1:
+; NACL: # %bb.0:
+; NACL-NEXT: lui $2, %hi(_gp_disp)
+; NACL-NEXT: addiu $2, $2, %lo(_gp_disp)
+; NACL-NEXT: bnez $4, $BB0_3
+; NACL-NEXT: addu $2, $2, $25
+; NACL-NEXT: # %bb.1:
+; NACL-NEXT: addiu $sp, $sp, -8
+; NACL-NEXT: sw $ra, 0($sp)
+; NACL-NEXT: lui $1, %hi(($BB0_4)-($BB0_2))
+; NACL-NEXT: bal $BB0_2
+; NACL-NEXT: addiu $1, $1, %lo(($BB0_4)-($BB0_2))
+; NACL-NEXT: $BB0_2:
+; NACL-NEXT: addu $1, $ra, $1
+; NACL-NEXT: lw $ra, 0($sp)
+; NACL-NEXT: addiu $sp, $sp, 8
+; NACL-NEXT: jr $1
+; NACL-NEXT: nop
+; NACL-NEXT: $BB0_3:
+; NACL-NEXT: lw $1, %got(x)($2)
+; NACL-NEXT: addiu $2, $zero, 1
+; NACL-NEXT: sw $2, 0($1)
+; NACL-NEXT: .p2align 4
+; NACL-NEXT: $BB0_4:
+; NACL-NEXT: jr $ra
+; NACL-NEXT: nop
+
+
+; Check the NaCl version. Check that sp change is not in the branch delay slot
+; of "jr $1" instruction. Check that target of indirect branch "jr $1" is
+; bundle aligned.
+
entry:
%cmp = icmp eq i32 %s, 0
br i1 %cmp, label %end, label %then
@@ -29,147 +326,4 @@ then:
end:
ret void
-
-; First check the normal version (without long branch). beqz jumps to return,
-; and fallthrough block stores 1 to global variable.
-
-; CHECK: lui $[[R0:[0-9]+]], %hi(_gp_disp)
-; CHECK: addiu $[[R0]], $[[R0]], %lo(_gp_disp)
-; CHECK: beqz $4, $[[BB0:BB[0-9_]+]]
-; CHECK: addu $[[GP:[0-9]+]], $[[R0]], $25
-; CHECK: lw $[[R1:[0-9]+]], %got(x)($[[GP]])
-; CHECK: addiu $[[R2:[0-9]+]], $zero, 1
-; CHECK: sw $[[R2]], 0($[[R1]])
-; CHECK: $[[BB0]]:
-; CHECK: jr $ra
-; CHECK: nop
-
-
-; Check the MIPS32 version. Check that branch logic is inverted, so that the
-; target of the new branch (bnez) is the fallthrough block of the original
-; branch. Check that fallthrough block of the new branch contains long branch
-; expansion which at the end indirectly jumps to the target of the original
-; branch.
-
-; O32: lui $[[R0:[0-9]+]], %hi(_gp_disp)
-; O32: addiu $[[R0]], $[[R0]], %lo(_gp_disp)
-; O32: bnez $4, $[[BB0:BB[0-9_]+]]
-; O32: addu $[[GP:[0-9]+]], $[[R0]], $25
-
-; Check for long branch expansion:
-; O32: addiu $sp, $sp, -8
-; O32-NEXT: sw $ra, 0($sp)
-; O32-NEXT: lui $1, %hi(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]]))
-; O32-NEXT: bal $[[BB1]]
-; O32-NEXT: addiu $1, $1, %lo(($[[BB2]])-($[[BB1]]))
-; O32-NEXT: $[[BB1]]:
-; O32-NEXT: addu $1, $ra, $1
-; O32-NEXT: lw $ra, 0($sp)
-; O32-NEXT: jr $1
-; O32-NEXT: addiu $sp, $sp, 8
-
-; O32: $[[BB0]]:
-; O32: lw $[[R1:[0-9]+]], %got(x)($[[GP]])
-; O32: addiu $[[R2:[0-9]+]], $zero, 1
-; O32: sw $[[R2]], 0($[[R1]])
-; O32: $[[BB2]]:
-; O32: jr $ra
-; O32: nop
-
-; In MIPS32R6 JR is an alias to JALR with $rd=0. As everything else remains the
-; same with the O32 prefix, we use -asm-show-inst in order to make sure that
-; the opcode of the MachineInst is a JALR.
-; O32-R6: JALR
-
-; Check the MIPS64 version.
-
-; N64: lui $[[R0:[0-9]+]], %hi(%neg(%gp_rel(test1)))
-; N64: bnez $4, [[BB0:\.LBB[0-9_]+]]
-; N64: daddu $[[R1:[0-9]+]], $[[R0]], $25
-
-; Check for long branch expansion:
-; N64: daddiu $sp, $sp, -16
-; N64-NEXT: sd $ra, 0($sp)
-; N64-NEXT: daddiu $1, $zero, %hi([[BB2:\.LBB[0-9_]+]]-[[BB1:\.LBB[0-9_]+]])
-; N64-NEXT: dsll $1, $1, 16
-; N64-NEXT: bal [[BB1]]
-; N64-NEXT: daddiu $1, $1, %lo([[BB2]]-[[BB1]])
-; N64-NEXT: [[BB1]]:
-; N64-NEXT: daddu $1, $ra, $1
-; N64-NEXT: ld $ra, 0($sp)
-; N64-NEXT: jr $1
-; N64-NEXT: daddiu $sp, $sp, 16
-
-; N64: [[BB0]]:
-; N64: daddiu $[[GP:[0-9]+]], $[[R1]], %lo(%neg(%gp_rel(test1)))
-; N64: addiu $[[R3:[0-9]+]], $zero, 1
-; N64: ld $[[R2:[0-9]+]], %got_disp(x)($[[GP]])
-; N64: sw $[[R3]], 0($[[R2]])
-; N64: [[BB2]]:
-; N64: jr $ra
-; N64: nop
-
-; In MIPS64R6 JR is an alias to JALR with $rd=0. As everything else remains the
-; same with the N64 prefix, we use -asm-show-inst in order to make sure that
-; the opcode of the MachineInst is a JALR.
-; N64-R6: JALR64
-
-
-; Check the microMIPS version.
-
-; MICROMIPS: lui $[[R0:[0-9]+]], %hi(_gp_disp)
-; MICROMIPS: addiu $[[R0]], $[[R0]], %lo(_gp_disp)
-; MICROMIPS: bnez $4, $[[BB0:BB[0-9_]+]]
-; MICROMIPS: addu $[[GP:[0-9]+]], $[[R0]], $25
-
-; Check for long branch expansion:
-; MICROMIPS: addiu $sp, $sp, -8
-; MICROMIPS-NEXT: sw $ra, 0($sp)
-; MICROMIPS-NEXT: lui $1, %hi(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]]))
-; MICROMIPS-NEXT: bal $[[BB1]]
-; MICROMIPS-NEXT: addiu $1, $1, %lo(($[[BB2]])-($[[BB1]]))
-; MICROMIPS-NEXT: $[[BB1]]:
-; MICROMIPS-NEXT: addu $1, $ra, $1
-; MICROMIPS-NEXT: lw $ra, 0($sp)
-; MICROMIPS-NEXT: jr $1
-; MICROMIPS-NEXT: addiu $sp, $sp, 8
-
-; MICROMIPS: $[[BB0]]:
-; MICROMIPS: lw $[[R1:[0-9]+]], %got(x)($[[GP]])
-; MICROMIPS: li16 $[[R2:[0-9]+]], 1
-; MICROMIPS: sw16 $[[R2]], 0($[[R1]])
-; MICROMIPS: $[[BB2]]:
-; MICROMIPS: jrc $ra
-
-
-; Check the NaCl version. Check that sp change is not in the branch delay slot
-; of "jr $1" instruction. Check that target of indirect branch "jr $1" is
-; bundle aligned.
-
-; NACL: lui $[[R0:[0-9]+]], %hi(_gp_disp)
-; NACL: addiu $[[R0]], $[[R0]], %lo(_gp_disp)
-; NACL: bnez $4, $[[BB0:BB[0-9_]+]]
-; NACL: addu $[[GP:[0-9]+]], $[[R0]], $25
-
-; Check for long branch expansion:
-; NACL: addiu $sp, $sp, -8
-; NACL-NEXT: sw $ra, 0($sp)
-; NACL-NEXT: lui $1, %hi(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]]))
-; NACL-NEXT: bal $[[BB1]]
-; NACL-NEXT: addiu $1, $1, %lo(($[[BB2]])-($[[BB1]]))
-; NACL-NEXT: $[[BB1]]:
-; NACL-NEXT: addu $1, $ra, $1
-; NACL-NEXT: lw $ra, 0($sp)
-; NACL-NEXT: addiu $sp, $sp, 8
-; NACL-NEXT: jr $1
-; NACL-NEXT: nop
-
-; NACL: $[[BB0]]:
-; NACL: lw $[[R1:[0-9]+]], %got(x)($[[GP]])
-; NACL: addiu $[[R2:[0-9]+]], $zero, 1
-; NACL: sw $[[R2]], 0($[[R1]])
-; NACL: .p2align 4
-; NACL-NEXT: $[[BB2]]:
-; NACL: jr $ra
-; NACL: nop
}
OpenPOWER on IntegriCloud