From 01cd91aaea652477da5eebdc9ceb9bfe13bf10dd Mon Sep 17 00:00:00 2001 From: Jessica Paquette Date: Wed, 28 Aug 2019 22:03:05 +0000 Subject: [PATCH 1/4] Add tie-breaker for register class sorting in getSuperRegForSubReg llvm::stable_sort is apparently not sufficient. Use the same tie-breaker/sorting style as TopoOrderRC fix bot failures. E.g. http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/19401/steps/test-check-all/logs/stdio llvm-svn: 370267 --- llvm/utils/TableGen/CodeGenTarget.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp index 14822024505ce..52a6bcd58bea5 100644 --- a/llvm/utils/TableGen/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/CodeGenTarget.cpp @@ -329,7 +329,14 @@ CodeGenTarget::getSuperRegForSubReg(const ValueTypeByHwMode &ValueTy, // Find and return the largest of our candidate classes. llvm::stable_sort(Candidates, [&](const CodeGenRegisterClass *A, const CodeGenRegisterClass *B) { - return A->getMembers().size() > B->getMembers().size(); + if (A->getMembers().size() > B->getMembers().size()) + return true; + + if (A->getMembers().size() < B->getMembers().size()) + return false; + + // Order by name as a tie-breaker. + return StringRef(A->getName()) < B->getName(); }); return Candidates[0]; From 59bb3609fa5f759b21d5e6e05e45d17a837352dd Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Wed, 28 Aug 2019 22:32:10 +0000 Subject: [PATCH 2/4] [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 --- llvm/lib/Target/Mips/Mips.td | 3 ++ llvm/lib/Target/Mips/Mips64InstrInfo.td | 34 +++++++++++++++++++ llvm/lib/Target/Mips/MipsInstrInfo.td | 4 +-- .../Mips/indirect-jump-hazard/long-calls.ll | 14 ++++---- llvm/test/CodeGen/Mips/long-calls.ll | 6 ++-- llvm/test/CodeGen/Mips/pr42736.ll | 28 +++++++++++++++ 6 files changed, 77 insertions(+), 12 deletions(-) create mode 100644 llvm/test/CodeGen/Mips/pr42736.ll diff --git a/llvm/lib/Target/Mips/Mips.td b/llvm/lib/Target/Mips/Mips.td index 7b83ea8535ae6..52f400f91f817 100644 --- a/llvm/lib/Target/Mips/Mips.td +++ b/llvm/lib/Target/Mips/Mips.td @@ -25,6 +25,8 @@ class PredicateControl { list GPRPredicates = []; // Predicates for the PTR size such as IsPTR64bit list PTRPredicates = []; + // Predicates for a 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 @@ class PredicateControl { 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 index 7f35280f79363..b2ae5dea4d7fa 100644 --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -682,6 +682,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; @@ -692,6 +706,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; @@ -705,6 +736,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 diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index 49413c90d0108..b42d718b7e83d 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -211,9 +211,9 @@ def HasCnMips : Predicate<"Subtarget->hasCnMips()">, 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 index 5be7bd1897b49..59a2c3eae6599 100644 --- 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 @@ define void @caller() { ; 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 index 9cd868902a06c..0b1a76d564a58 100644 --- a/llvm/test/CodeGen/Mips/long-calls.ll +++ b/llvm/test/CodeGen/Mips/long-calls.ll @@ -43,9 +43,11 @@ define void @caller() { ; 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 index 0000000000000..c0dbadb507073 --- /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() From 027f1da0104a4e919ff53914707442c83933ef6a Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Wed, 28 Aug 2019 22:32:16 +0000 Subject: [PATCH 3/4] [mips] Add an empty line to separate different patterns. NFC llvm-svn: 370269 --- llvm/lib/Target/Mips/Mips64InstrInfo.td | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td index b2ae5dea4d7fa..7dea56c01c82f 100644 --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -651,6 +651,7 @@ def : MipsPat<(MipsTlsHi tglobaltlsaddr:$in), (LUi64 tglobaltlsaddr:$in)>, 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)), From 6c7687ed6770e17f3538a222b0f7925480e0cb38 Mon Sep 17 00:00:00 2001 From: Erik Pilkington Date: Wed, 28 Aug 2019 22:38:36 +0000 Subject: [PATCH 4/4] Fix a passing XFAIL test Now that we can gracefully handle stack exhaustion, this test was passing in darwin && asan. Instead, just unsupport it when threading is unavailable. llvm-svn: 370270 --- clang/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp b/clang/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp index 61272b1ceea2c..2d5f2e4c34ff6 100644 --- a/clang/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp +++ b/clang/test/CodeGenCXX/castexpr-basepathsize-threshold.cpp @@ -3,9 +3,9 @@ // https://bugs.llvm.org/show_bug.cgi?id=38356 // We only check that we do not crash. -// ASAN increases stack usage, so we are hitting stack overflow before reaching -// recursive template instantiation limit. -// XFAIL: darwin && asan +// This test can exceed stack usage in some configurations, so unless we can +// properly handle that don't run it. +// REQUIRES: thread_support template struct d : d {};