diff --git a/llvm/lib/Target/Mips/Mips.td b/llvm/lib/Target/Mips/Mips.td --- a/llvm/lib/Target/Mips/Mips.td +++ b/llvm/lib/Target/Mips/Mips.td @@ -25,6 +25,8 @@ list GPRPredicates = []; // Predicates for the PTR size such as IsPTR64bit list PTRPredicates = []; + // Predicates for the symbol's size such as hasSym32 + list SYMPredicates = []; // Predicates for the FGR size and layout such as IsFP64bit list FGRPredicates = []; // Predicates for the instruction group membership such as ISA's. @@ -38,6 +40,7 @@ list Predicates = !listconcat(EncodingPredicates, GPRPredicates, PTRPredicates, + SYMPredicates, FGRPredicates, InsnPredicates, HardFloatPredicate, diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -651,6 +651,7 @@ let AdditionalPredicates = [NotInMicroMips] in { def : MipsPat<(MipsJmpLink (i64 texternalsym:$dst)), (JAL texternalsym:$dst)>, ISA_MIPS3, GPR_64, SYM_64; + def : MipsPat<(MipsHighest (i64 tglobaladdr:$in)), (LUi64 tglobaladdr:$in)>, ISA_MIPS3, GPR_64, SYM_64; def : MipsPat<(MipsHighest (i64 tblockaddress:$in)), @@ -682,6 +683,20 @@ (DADDiu GPR64:$hi, tjumptable:$lo)>, ISA_MIPS3, GPR_64, SYM_64; def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tconstpool:$lo))), (DADDiu GPR64:$hi, tconstpool:$lo)>, ISA_MIPS3, GPR_64, SYM_64; + def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 texternalsym:$lo))), + (DADDiu GPR64:$hi, texternalsym:$lo)>, + ISA_MIPS3, GPR_64, SYM_64; + + def : MipsPat<(MipsHi (i64 tglobaladdr:$in)), + (DADDiu ZERO_64, tglobaladdr:$in)>, ISA_MIPS3, GPR_64, SYM_64; + def : MipsPat<(MipsHi (i64 tblockaddress:$in)), + (DADDiu ZERO_64, tblockaddress:$in)>, ISA_MIPS3, GPR_64, SYM_64; + def : MipsPat<(MipsHi (i64 tjumptable:$in)), + (DADDiu ZERO_64, tjumptable:$in)>, ISA_MIPS3, GPR_64, SYM_64; + def : MipsPat<(MipsHi (i64 tconstpool:$in)), + (DADDiu ZERO_64, tconstpool:$in)>, ISA_MIPS3, GPR_64, SYM_64; + def : MipsPat<(MipsHi (i64 texternalsym:$in)), + (DADDiu ZERO_64, texternalsym:$in)>, ISA_MIPS3, GPR_64, SYM_64; def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tglobaladdr:$lo))), (DADDiu GPR64:$hi, tglobaladdr:$lo)>, ISA_MIPS3, GPR_64, SYM_64; @@ -692,6 +707,23 @@ (DADDiu GPR64:$hi, tjumptable:$lo)>, ISA_MIPS3, GPR_64, SYM_64; def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tconstpool:$lo))), (DADDiu GPR64:$hi, tconstpool:$lo)>, ISA_MIPS3, GPR_64, SYM_64; + def : MipsPat<(add GPR64:$hi, (MipsHi (i64 texternalsym:$lo))), + (DADDiu GPR64:$hi, texternalsym:$lo)>, + ISA_MIPS3, GPR_64, SYM_64; + + def : MipsPat<(MipsLo (i64 tglobaladdr:$in)), + (DADDiu ZERO_64, tglobaladdr:$in)>, ISA_MIPS3, GPR_64, SYM_64; + def : MipsPat<(MipsLo (i64 tblockaddress:$in)), + (DADDiu ZERO_64, tblockaddress:$in)>, ISA_MIPS3, GPR_64, SYM_64; + def : MipsPat<(MipsLo (i64 tjumptable:$in)), + (DADDiu ZERO_64, tjumptable:$in)>, ISA_MIPS3, GPR_64, SYM_64; + def : MipsPat<(MipsLo (i64 tconstpool:$in)), + (DADDiu ZERO_64, tconstpool:$in)>, ISA_MIPS3, GPR_64, SYM_64; + def : MipsPat<(MipsLo (i64 tglobaltlsaddr:$in)), + (DADDiu ZERO_64, tglobaltlsaddr:$in)>, + ISA_MIPS3, GPR_64, SYM_64; + def : MipsPat<(MipsLo (i64 texternalsym:$in)), + (DADDiu ZERO_64, texternalsym:$in)>, ISA_MIPS3, GPR_64, SYM_64; def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tglobaladdr:$lo))), (DADDiu GPR64:$hi, tglobaladdr:$lo)>, ISA_MIPS3, GPR_64, SYM_64; @@ -705,6 +737,9 @@ def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tglobaltlsaddr:$lo))), (DADDiu GPR64:$hi, tglobaltlsaddr:$lo)>, ISA_MIPS3, GPR_64, SYM_64; + def : MipsPat<(add GPR64:$hi, (MipsLo (i64 texternalsym:$lo))), + (DADDiu GPR64:$hi, texternalsym:$lo)>, + ISA_MIPS3, GPR_64, SYM_64; } // gp_rel relocs diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -211,9 +211,9 @@ AssemblerPredicate<"FeatureCnMips">; def NotCnMips : Predicate<"!Subtarget->hasCnMips()">, AssemblerPredicate<"!FeatureCnMips">; -def IsSym32 : Predicate<"Subtarget->HasSym32()">, +def IsSym32 : Predicate<"Subtarget->hasSym32()">, AssemblerPredicate<"FeatureSym32">; -def IsSym64 : Predicate<"!Subtarget->HasSym32()">, +def IsSym64 : Predicate<"!Subtarget->hasSym32()">, AssemblerPredicate<"!FeatureSym32">; def IsN64 : Predicate<"Subtarget->isABI_N64()">; def IsNotN64 : Predicate<"!Subtarget->isABI_N64()">; diff --git a/llvm/test/CodeGen/Mips/indirect-jump-hazard/long-calls.ll b/llvm/test/CodeGen/Mips/indirect-jump-hazard/long-calls.ll --- a/llvm/test/CodeGen/Mips/indirect-jump-hazard/long-calls.ll +++ b/llvm/test/CodeGen/Mips/indirect-jump-hazard/long-calls.ll @@ -74,20 +74,18 @@ ; N64-NEXT: daddiu $25, $1, %lo(callee) ; N64-NEXT: jalr.hb $25 ; N64-NEXT: nop -; N64-NEXT: daddiu $1, $zero, %higher(memset) -; N64-NEXT: lui $2, %highest(memset) -; N64-NEXT: daddu $1, $2, $1 -; N64-NEXT: dsll $1, $1, 16 -; N64-NEXT: lui $2, %hi(memset) -; N64-NEXT: daddu $1, $1, $2 -; N64-NEXT: dsll $1, $1, 16 -; N64-NEXT: daddiu $25, $1, %lo(memset) ; N64-NEXT: lui $1, %highest(val) ; N64-NEXT: daddiu $1, $1, %higher(val) ; N64-NEXT: dsll $1, $1, 16 ; N64-NEXT: daddiu $1, $1, %hi(val) ; N64-NEXT: dsll $1, $1, 16 +; N64-NEXT: lui $2, %highest(memset) ; N64-NEXT: daddiu $4, $1, %lo(val) +; N64-NEXT: daddiu $1, $2, %higher(memset) +; N64-NEXT: dsll $1, $1, 16 +; N64-NEXT: daddiu $1, $1, %hi(memset) +; N64-NEXT: dsll $1, $1, 16 +; N64-NEXT: daddiu $25, $1, %lo(memset) ; N64-NEXT: daddiu $5, $zero, 0 ; N64-NEXT: jalr.hb $25 ; N64-NEXT: daddiu $6, $zero, 80 diff --git a/llvm/test/CodeGen/Mips/long-calls.ll b/llvm/test/CodeGen/Mips/long-calls.ll --- a/llvm/test/CodeGen/Mips/long-calls.ll +++ b/llvm/test/CodeGen/Mips/long-calls.ll @@ -43,9 +43,11 @@ ; ON64: daddiu $25, $1, %lo(callee) ; ON64: jalr $25 -; ON64: daddiu $1, $zero, %higher(memset) ; ON64: lui $2, %highest(memset) -; ON64: lui $2, %hi(memset) +; ON64: daddiu $1, $2, %higher(memset) +; ON64: dsll $1, $1, 16 +; ON64: daddiu $1, $1, %hi(memset) +; ON64: dsll $1, $1, 16 ; ON64: daddiu $25, $1, %lo(memset) ; ON64: jalr $25 diff --git a/llvm/test/CodeGen/Mips/pr42736.ll b/llvm/test/CodeGen/Mips/pr42736.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/Mips/pr42736.ll @@ -0,0 +1,28 @@ +; RUN: llc -mtriple=mips64-linux-gnuabi64 \ +; RUN: -relocation-model=pic < %s | FileCheck %s -check-prefix=PIC +; RUN: llc -mtriple=mips64-linux-gnuabi64 \ +; RUN: -relocation-model=static < %s | FileCheck %s -check-prefix=STATIC + +define void @bar1() nounwind { +entry: +; PIC: lui $[[R0:[0-9]+]], 4095 +; PIC-NEXT: ori $[[R0]], $[[R0]], 65535 +; PIC-NEXT: ld $[[R1:[0-9]+]], %got_disp(foo)(${{[0-9]+}}) +; PIC-NEXT: and $[[R1]], $[[R1]], $[[R0]] +; PIC-NEXT: sd $[[R1]] + +; STATIC: lui $[[R0:[0-9]+]], 4095 +; STATIC-NEXT: ori $[[R0]], $[[R0]], 65535 +; STATIC-NEXT: daddiu $[[R1:[0-9]+]], $zero, %hi(foo) +; STATIC-NEXT: dsll $[[R1]], $[[R1]], 16 +; STATIC-NEXT: daddiu $[[R1]], $[[R1]], %lo(foo) +; STATIC-NEXT: and $[[R0]], $[[R1]], $[[R0]] +; STATIC-NEXT: sd $[[R0]] + + %val = alloca i64, align 8 + store i64 and (i64 ptrtoint (void ()* @foo to i64), i64 268435455), i64* %val, align 8 + %0 = load i64, i64* %val, align 8 + ret void +} + +declare void @foo()