Merge commit f46ba4f07 from llvm git (by Simon Atanasyan):
[mips] Use less registers to load address of TargetExternalSymbol There is no pattern matched `add hi, (MipsLo texternalsym)`. As a result, loading an address of 32-bit symbol requires two registers and one more additional instruction: ``` addiu $1, $zero, %lo(foo) lui $2, %hi(foo) addu $25, $2, $1 ``` This patch adds the missed pattern and enables generation more effective set of instructions: ``` lui $1, %hi(foo) addiu $25, $1, %lo(foo) ``` Differential Revision: https://reviews.llvm.org/D66771 llvm-svn: 370196 Merge commit 59bb3609f from llvm git (by Simon Atanasyan): [mips] Fix 64-bit address loading in case of applying 32-bit mask to the result If result of 64-bit address loading combines with 32-bit mask, LLVM tries to optimize the code and remove "redundant" loading of upper 32-bits of the address. It leads to incorrect code on MIPS64 targets. MIPS backend creates the following chain of commands to load 64-bit address in the `MipsTargetLowering::getAddrNonPICSym64` method: ``` (add (shl (add (shl (add %highest(sym), %higher(sym)), 16), %hi(sym)), 16), %lo(%sym)) ``` If the mask presents, LLVM decides to optimize the chain of commands. It really does not make sense to load upper 32-bits because the 0x0fffffff mask anyway clears them. After removing redundant commands we get this chain: ``` (add (shl (%hi(sym), 16), %lo(%sym)) ``` There is no patterns matched `(MipsHi (i64 symbol))`. Due a bug in `SYM_32` predicate definition, backend incorrectly selects a pattern for a 32-bit symbols and uses the `lui` instruction for loading `%hi(sym)`. As a result we get incorrect set of instructions with unnecessary 16-bit left shifting: ``` lui at,0x0 R_MIPS_HI16 foo dsll at,at,0x10 daddiu at,at,0 R_MIPS_LO16 foo ``` This patch resolves two problems: - Fix `SYM_32/SYM_64` predicates to prevent selection of patterns dedicated to 32-bit symbols in case of using N64 ABI. - Add missed patterns for 64-bit symbols for `%hi/%lo`. Fix PR42736. Differential Revision: https://reviews.llvm.org/D66228 llvm-svn: 370268 These two commits fix a miscompilation of the kernel for mips64, and should allow clang to be used as the default compiler for mips64. Requested by: arichards MFC after: 3 days
This commit is contained in:
parent
aaeffe5b70
commit
f10421e96d
@ -25,6 +25,8 @@ class PredicateControl {
|
||||
list<Predicate> GPRPredicates = [];
|
||||
// Predicates for the PTR size such as IsPTR64bit
|
||||
list<Predicate> PTRPredicates = [];
|
||||
// Predicates for a symbol's size such as hasSym32.
|
||||
list<Predicate> SYMPredicates = [];
|
||||
// Predicates for the FGR size and layout such as IsFP64bit
|
||||
list<Predicate> FGRPredicates = [];
|
||||
// Predicates for the instruction group membership such as ISA's.
|
||||
@ -38,6 +40,7 @@ class PredicateControl {
|
||||
list<Predicate> Predicates = !listconcat(EncodingPredicates,
|
||||
GPRPredicates,
|
||||
PTRPredicates,
|
||||
SYMPredicates,
|
||||
FGRPredicates,
|
||||
InsnPredicates,
|
||||
HardFloatPredicate,
|
||||
|
@ -700,6 +700,20 @@ let AdditionalPredicates = [NotInMicroMips] in {
|
||||
(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;
|
||||
@ -710,6 +724,23 @@ let AdditionalPredicates = [NotInMicroMips] in {
|
||||
(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;
|
||||
@ -723,6 +754,9 @@ let AdditionalPredicates = [NotInMicroMips] in {
|
||||
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
|
||||
|
@ -215,9 +215,9 @@ def HasCnMipsP : Predicate<"Subtarget->hasCnMipsP()">,
|
||||
AssemblerPredicate<"FeatureCnMipsP">;
|
||||
def NotCnMipsP : Predicate<"!Subtarget->hasCnMipsP()">,
|
||||
AssemblerPredicate<"!FeatureCnMipsP">;
|
||||
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()">;
|
||||
@ -3173,6 +3173,8 @@ multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
|
||||
(Addiu GPROpnd:$hi, tconstpool:$lo)>;
|
||||
def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaltlsaddr:$lo)),
|
||||
(Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
|
||||
def : MipsPat<(add GPROpnd:$hi, (MipsLo texternalsym:$lo)),
|
||||
(Addiu GPROpnd:$hi, texternalsym:$lo)>;
|
||||
}
|
||||
|
||||
// wrapper_pic
|
||||
|
Loading…
Reference in New Issue
Block a user