[llvm] [Mips] Add MipsPat `add $gp, (select $cond, tglobaladdr, tglobaladdr)` to parse MipsISD::GPRel TargetGlobalAddress (PR #165531)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 1 01:05:46 PST 2025
https://github.com/yingopq updated https://github.com/llvm/llvm-project/pull/165531
>From 5cd8861928d3dbca99524ebf4e6c1725806b4350 Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Wed, 29 Oct 2025 05:21:46 -0400
Subject: [PATCH] [Mips] Add MipsPat to parse MipsISD::GPRel
TargetGlobalAddress
The original logic:
```
SelectionDAG has 17 nodes:
t0: ch,glue = EntryToken
t2: i64,ch = CopyFromReg t0, Register:i64 %0
t11: i32 = truncate t2
t14: i32 = and t11, Constant:i32<1>
t20: i64 = MipsISD::GPRel TargetGlobalAddress:i64<ptr @.str.1> 0 [TF=3]
t21: i64 = add Register:i64 $gp_64, t20
t16: i64 = MipsISD::GPRel TargetGlobalAddress:i64<ptr @.str> 0 [TF=3]
t18: i64 = add Register:i64 $gp_64, t16
t7: i64 = select t14, t21, t18
```
When SelectionDAG process visitSELECT, would fold select(cond,
binop(x, y), binop(x, z)) to binop(x, select(cond, y, z)).
As follows:
```
SelectionDAG has 16 nodes:
t0: ch,glue = EntryToken
t2: i64,ch = CopyFromReg t0, Register:i64 %0
t11: i32 = truncate t2
t14: i32 = and t11, Constant:i32<1>
t20: i64 = MipsISD::GPRel TargetGlobalAddress:i64<ptr @.str.1> 0 [TF=3]
t16: i64 = MipsISD::GPRel TargetGlobalAddress:i64<ptr @.str> 0 [TF=3]
t22: i64 = select t14, t20, t16
t23: i64 = add Register:i64 $gp_64, t22
```
Therefore, the original MipsPat `add GPR64:$gp, (MipsGPRel
tglobaladdr:$in)` is no longer available. And there would be an assert:
```
ISEL: Starting selection on root node: t20: i64 = MipsISD::GPRel TargetGlobalAddress:i64<ptr @.str.1> 0 [TF=3]
ISEL: Starting pattern match
Initial Opcode index to 0
Match failed at index 0
LLVM ERROR: Cannot select: t20: i64 = MipsISD::GPRel TargetGlobalAddress:i64<ptr @.str.1> 0 [TF=3]
```
So we add a new MipsPat `def : MipsPat<(MipsGPRel tglobaladdr:$in),
(DADDiu ZERO_64, tglobaladdr:$in)>, ISA_MIPS3, ABI_N64;`
to parse MipsISD::GPRel TargetGlobalAddress.
Fix #142060.
---
llvm/lib/Target/Mips/Mips64InstrInfo.td | 3 +++
.../CodeGen/Mips/llvm-ir/select-globaladdr.ll | 23 +++++++++++++++++++
2 files changed, 26 insertions(+)
create mode 100644 llvm/test/CodeGen/Mips/llvm-ir/select-globaladdr.ll
diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td
index 49e463cfd212c..ef4eea8c50dc6 100644
--- a/llvm/lib/Target/Mips/Mips64InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td
@@ -770,6 +770,9 @@ let AdditionalPredicates = [NotInMicroMips] in {
ISA_MIPS3, GPR_64, SYM_64;
}
+def : MipsPat<(MipsGPRel tglobaladdr:$in),
+ (DADDiu ZERO_64, tglobaladdr:$in)>, ISA_MIPS3, ABI_N64;
+
// gp_rel relocs
def : MipsPat<(add GPR64:$gp, (MipsGPRel tglobaladdr:$in)),
(DADDiu GPR64:$gp, tglobaladdr:$in)>, ISA_MIPS3, ABI_N64;
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/select-globaladdr.ll b/llvm/test/CodeGen/Mips/llvm-ir/select-globaladdr.ll
new file mode 100644
index 0000000000000..7914c692c6e62
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/llvm-ir/select-globaladdr.ll
@@ -0,0 +1,23 @@
+; RUN: llc < %s -mattr +noabicalls -mgpopt | FileCheck %s -check-prefixes=MIPS64
+
+target datalayout = "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "mips64-unknown-linux-muslabi64"
+
+ at .str = external constant [6 x i8]
+ at .str.1 = external constant [6 x i8]
+
+define ptr @tst_select_ptr_ptr(i1 %tobool.not) {
+entry:
+; MIPS64-LABEL: tst_select_ptr_ptr:
+; MIPS64: # %bb.0: # %entry
+; MIPS64: sll $1, $4, 0
+; MIPS64: andi $1, $1, 1
+; MIPS64: daddiu $2, $zero, %gp_rel(.str)
+; MIPS64: daddiu $3, $zero, %gp_rel(.str.1)
+; MIPS64: movn $2, $3, $1
+; MIPS64: jr $ra
+; MIPS64: daddu $2, $gp, $2
+
+ %cond = select i1 %tobool.not, ptr @.str.1, ptr @.str
+ ret ptr %cond
+}
More information about the llvm-commits
mailing list