[llvm-branch-commits] [llvm] release/23.x: [MIPS] Don't mark SLL64_64 as isMoveReg (#214060) (PR #217798)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Aug 20 18:47:10 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-mips
Author: llvmbot
<details>
<summary>Changes</summary>
Backport c3a7864be42e5d0aeb042b27a108e635c89cc8bf
Requested by: @<!-- -->brad0
---
Full diff: https://github.com/llvm/llvm-project/pull/217798.diff
3 Files Affected:
- (modified) llvm/lib/Target/Mips/Mips64InstrInfo.td (+7-6)
- (modified) llvm/test/CodeGen/Mips/madd-msub.ll (+42-42)
- (added) llvm/test/CodeGen/Mips/sll64_64-is-not-a-copy.mir (+134)
``````````diff
diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td
index 1321dd3bde211..b6d820bbc1025 100644
--- a/llvm/lib/Target/Mips/Mips64InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td
@@ -426,12 +426,13 @@ let isCodeGenOnly = 1, AdditionalPredicates = [NotInMicroMips] in {
let isCodeGenOnly = 1, rs = 0, shamt = 0 in {
def DSLL64_32 : FR<0x00, 0x3c, (outs GPR64:$rd), (ins GPR32:$rt),
"dsll\t$rd, $rt, 32", []>, GPR_64;
- let isMoveReg = 1 in {
- def SLL64_32 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR32:$rt),
- "sll\t$rd, $rt, 0", []>, GPR_64;
- def SLL64_64 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR64:$rt),
- "sll\t$rd, $rt, 0", []>, GPR_64;
- }
+ let isMoveReg = 1 in
+ def SLL64_32 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR32:$rt),
+ "sll\t$rd, $rt, 0", []>, GPR_64;
+ // Not isMoveReg: with a 64-bit source this truncates to 32 bits and
+ // sign-extends, which is not value-preserving.
+ def SLL64_64 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR64:$rt),
+ "sll\t$rd, $rt, 0", []>, GPR_64;
}
// We need the following pseudo instruction to avoid offset calculation for
diff --git a/llvm/test/CodeGen/Mips/madd-msub.ll b/llvm/test/CodeGen/Mips/madd-msub.ll
index 6bb1ea48184f9..f0d6649e767a0 100644
--- a/llvm/test/CodeGen/Mips/madd-msub.ll
+++ b/llvm/test/CodeGen/Mips/madd-msub.ll
@@ -42,22 +42,22 @@ define i64 @madd1(i32 %a, i32 %b, i32 %c) nounwind readnone {
;
; 64-LABEL: madd1:
; 64: # %bb.0: # %entry
-; 64-NEXT: sll $4, $4, 0
-; 64-NEXT: sll $5, $5, 0
-; 64-NEXT: dmult $5, $4
+; 64-NEXT: sll $1, $4, 0
+; 64-NEXT: sll $2, $5, 0
+; 64-NEXT: dmult $2, $1
; 64-NEXT: mflo $1
-; 64-NEXT: sll $6, $6, 0
+; 64-NEXT: sll $2, $6, 0
; 64-NEXT: jr $ra
-; 64-NEXT: daddu $2, $1, $6
+; 64-NEXT: daddu $2, $1, $2
;
; 64R6-LABEL: madd1:
; 64R6: # %bb.0: # %entry
-; 64R6-NEXT: sll $4, $4, 0
-; 64R6-NEXT: sll $5, $5, 0
-; 64R6-NEXT: dmul $1, $5, $4
-; 64R6-NEXT: sll $6, $6, 0
+; 64R6-NEXT: sll $1, $4, 0
+; 64R6-NEXT: sll $2, $5, 0
+; 64R6-NEXT: dmul $1, $2, $1
+; 64R6-NEXT: sll $2, $6, 0
; 64R6-NEXT: jr $ra
-; 64R6-NEXT: daddu $2, $1, $6
+; 64R6-NEXT: daddu $2, $1, $2
;
; 16-LABEL: madd1:
; 16: # %bb.0: # %entry
@@ -173,18 +173,18 @@ define i64 @madd3(i32 %a, i32 %b, i64 %c) nounwind readnone {
;
; 64-LABEL: madd3:
; 64: # %bb.0: # %entry
-; 64-NEXT: sll $4, $4, 0
-; 64-NEXT: sll $5, $5, 0
-; 64-NEXT: dmult $5, $4
+; 64-NEXT: sll $1, $4, 0
+; 64-NEXT: sll $2, $5, 0
+; 64-NEXT: dmult $2, $1
; 64-NEXT: mflo $1
; 64-NEXT: jr $ra
; 64-NEXT: daddu $2, $1, $6
;
; 64R6-LABEL: madd3:
; 64R6: # %bb.0: # %entry
-; 64R6-NEXT: sll $4, $4, 0
-; 64R6-NEXT: sll $5, $5, 0
-; 64R6-NEXT: dmul $1, $5, $4
+; 64R6-NEXT: sll $1, $4, 0
+; 64R6-NEXT: sll $2, $5, 0
+; 64R6-NEXT: dmul $1, $2, $1
; 64R6-NEXT: jr $ra
; 64R6-NEXT: daddu $2, $1, $6
;
@@ -291,22 +291,22 @@ define i64 @msub1(i32 %a, i32 %b, i32 %c) nounwind readnone {
;
; 64-LABEL: msub1:
; 64: # %bb.0: # %entry
-; 64-NEXT: sll $4, $4, 0
-; 64-NEXT: sll $5, $5, 0
-; 64-NEXT: dmult $5, $4
+; 64-NEXT: sll $1, $4, 0
+; 64-NEXT: sll $2, $5, 0
+; 64-NEXT: dmult $2, $1
; 64-NEXT: mflo $1
-; 64-NEXT: sll $6, $6, 0
+; 64-NEXT: sll $2, $6, 0
; 64-NEXT: jr $ra
-; 64-NEXT: dsubu $2, $6, $1
+; 64-NEXT: dsubu $2, $2, $1
;
; 64R6-LABEL: msub1:
; 64R6: # %bb.0: # %entry
-; 64R6-NEXT: sll $4, $4, 0
-; 64R6-NEXT: sll $5, $5, 0
-; 64R6-NEXT: dmul $1, $5, $4
-; 64R6-NEXT: sll $6, $6, 0
+; 64R6-NEXT: sll $1, $4, 0
+; 64R6-NEXT: sll $2, $5, 0
+; 64R6-NEXT: dmul $1, $2, $1
+; 64R6-NEXT: sll $2, $6, 0
; 64R6-NEXT: jr $ra
-; 64R6-NEXT: dsubu $2, $6, $1
+; 64R6-NEXT: dsubu $2, $2, $1
;
; 16-LABEL: msub1:
; 16: # %bb.0: # %entry
@@ -424,18 +424,18 @@ define i64 @msub3(i32 %a, i32 %b, i64 %c) nounwind readnone {
;
; 64-LABEL: msub3:
; 64: # %bb.0: # %entry
-; 64-NEXT: sll $4, $4, 0
-; 64-NEXT: sll $5, $5, 0
-; 64-NEXT: dmult $5, $4
+; 64-NEXT: sll $1, $4, 0
+; 64-NEXT: sll $2, $5, 0
+; 64-NEXT: dmult $2, $1
; 64-NEXT: mflo $1
; 64-NEXT: jr $ra
; 64-NEXT: dsubu $2, $6, $1
;
; 64R6-LABEL: msub3:
; 64R6: # %bb.0: # %entry
-; 64R6-NEXT: sll $4, $4, 0
-; 64R6-NEXT: sll $5, $5, 0
-; 64R6-NEXT: dmul $1, $5, $4
+; 64R6-NEXT: sll $1, $4, 0
+; 64R6-NEXT: sll $2, $5, 0
+; 64R6-NEXT: dmul $1, $2, $1
; 64R6-NEXT: jr $ra
; 64R6-NEXT: dsubu $2, $6, $1
;
@@ -546,22 +546,22 @@ define i64 @msub5(i32 %a, i32 %b, i32 %c) {
;
; 64-LABEL: msub5:
; 64: # %bb.0: # %entry
-; 64-NEXT: sll $4, $4, 0
-; 64-NEXT: sll $5, $5, 0
-; 64-NEXT: dmult $5, $4
+; 64-NEXT: sll $1, $4, 0
+; 64-NEXT: sll $2, $5, 0
+; 64-NEXT: dmult $2, $1
; 64-NEXT: mflo $1
-; 64-NEXT: sll $6, $6, 0
+; 64-NEXT: sll $2, $6, 0
; 64-NEXT: jr $ra
-; 64-NEXT: dsubu $2, $1, $6
+; 64-NEXT: dsubu $2, $1, $2
;
; 64R6-LABEL: msub5:
; 64R6: # %bb.0: # %entry
-; 64R6-NEXT: sll $4, $4, 0
-; 64R6-NEXT: sll $5, $5, 0
-; 64R6-NEXT: dmul $1, $5, $4
-; 64R6-NEXT: sll $6, $6, 0
+; 64R6-NEXT: sll $1, $4, 0
+; 64R6-NEXT: sll $2, $5, 0
+; 64R6-NEXT: dmul $1, $2, $1
+; 64R6-NEXT: sll $2, $6, 0
; 64R6-NEXT: jr $ra
-; 64R6-NEXT: dsubu $2, $1, $6
+; 64R6-NEXT: dsubu $2, $1, $2
;
; 16-LABEL: msub5:
; 16: # %bb.0: # %entry
diff --git a/llvm/test/CodeGen/Mips/sll64_64-is-not-a-copy.mir b/llvm/test/CodeGen/Mips/sll64_64-is-not-a-copy.mir
new file mode 100644
index 0000000000000..aa7ac7fc7b441
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/sll64_64-is-not-a-copy.mir
@@ -0,0 +1,134 @@
+# NOTE: assertions are hand-written, not autogenerated.
+# RUN: llc -mtriple=mips64 -mcpu=mips3 -run-pass=greedy -o - %s | FileCheck %s
+
+# SLL64_64 is `sll $rd, $rt, 0` with a GPR64 source, so it truncates its operand to 32 bits and
+# sign-extends the result. It is therefore not a register move, and must survive register
+# allocation: deleting it, or replacing its uses with its source, silently drops the truncation.
+#
+# This function reaches register allocation with four live SLL64_64 instructions. Marking the
+# instruction isMoveReg used to make the allocator drop one of them.
+
+# CHECK-COUNT-4: = SLL64_64
+
+--- |
+ target datalayout = "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+ target triple = "mips64-unknown-unknown"
+
+ define void @test() { ret void }
+...
+---
+name: test
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $a0_64, $a1_64, $a2_64, $a3_64
+ %109:gpr64 = COPY $a3_64
+ %108:gpr64 = COPY $a2_64
+ %107:gpr64 = COPY $a1_64
+ %106:gpr64 = COPY $a0_64
+ %111:gpr32 = LUi 1023
+ %112:gpr32 = ORi %111, 65535
+ %3:gpr64 = LD %106, 16
+ %114:gpr32 = SLL %3.sub_32, 0
+ %115:gpr32 = AND %114, %112
+ %116:gpr64 = DSRL %3, 32
+ %118:gpr32 = SLL %116.sub_32, 0
+ %119:gpr32 = ANDi %118, 1023
+ %120:gpr32 = LW %109, 32
+ %7:gpr32 = SUBu %115, %120
+ %2:gpr64 = LD %106, 8
+ %0:gpr64 = LD %106, 0
+ %121:gpr32 = SLL %119, 1
+ %271:gpr64 = DADDiu $zero_64, 0
+ %6:gpr32 = ADDiu %121, 2
+ %136:gpr64 = DADDiu $zero_64, 3
+ %137:gpr64 = DSLL %136, 52
+ %138:gpr64 = AND64 %0, %137
+ %139:gpr64 = DADDiu $zero_64, 13107
+ %140:gpr64 = DSLL %139, 18
+ %141:gpr64 = DADDiu %140, 768
+ %142:gpr64 = AND64 %0, %141
+ %143:gpr64 = DADDiu $zero_64, 8211
+ %144:gpr64 = DSLL %143, 18
+ %145:gpr64 = DADDiu %144, 512
+ %146:gpr64 = DSRL %3, 51
+ %148:gpr32 = nuw nsw SLL %146.sub_32, 0
+ %153:gpr64 = DADDiu $zero_64, 1
+ %154:gpr64 = DSLL %153, 55
+ %155:gpr64 = DADDiu $zero_64, -4
+ %215:gpr64 = LUi64 3
+ %216:gpr64 = ORi64 %215, 65535
+ J %bb.2, implicit-def dead $at
+ bb.1:
+ RetRA
+ bb.2:
+ %124:gpr64 = nuw nsw DSLL %271, 3
+ %11:gpr64 = nuw DADDu %107, %124
+ %12:gpr64 = LD %11, 0
+ BNE64 %138, $zero_64, %bb.97, implicit-def dead $at
+ BNE64 %142, %145, %bb.96, implicit-def dead $at
+ bb.11:
+ %149:gpr32 = ANDi %148, 2
+ %151:gpr32 = SLL %12.sub_32, 0
+ %25:gpr64 = LD %11, 16
+ %23:gpr64 = LD %11, 8
+ %152:gpr64 = DSRA %23, 30
+ %19:gpr64 = AND64 %12, %154
+ %24:gpr64 = AND64 %152, %155
+ %26:gpr64 = SLL64_64 %25
+ %21:gpr32 = SLL %151, 2
+ %156:gpr32 = SLL %151, 18
+ %157:gpr64 = DSRL %12, 14
+ %20:gpr32 = SLL %157.sub_32, 0
+ %56:gpr32 = SRA %156, 18
+ %159:gpr64 = LD %11, 24
+ %162:gpr64 = DSRL %2, 12
+ %165:gpr64 = ANDi64 %162, 4095
+ %167:gpr64 = DSRA %159, 30
+ %168:gpr64 = DSRA %25, 30
+ %57:gpr64 = AND64 %168, %155
+ %58:gpr64 = AND64 %167, %155
+ %34:gpr32 = SRA %21, 18
+ %33:gpr64 = SLL64_64 %159
+ %32:gpr64 = nsw DADDiu %165, -1
+ %172:gpr64 = DSRL %2, 44
+ %173:gpr64 = ANDi64 %172, 4095
+ %174:gpr64 = nuw nsw DADDiu %173, 3
+ %30:gpr64 = DSRL %174, 2
+ %35:gpr32 = COPY %56
+ %38:gpr64 = SLL64_64 %23
+ %283:gpr64 = COPY %30
+ %44:gpr32 = exact SRA %56, 2
+ %254:acc64 = PseudoMULT %6, %44
+ %255:gpr32 = PseudoMFLO %254
+ %256:gpr32 = ADDu %7, %255
+ %258:gpr32 = SLL %283.sub_32, 1
+ %24:gpr64 = DADDu %24, %38
+ BNE %56, %35, %bb.40, implicit-def $at
+ bb.40:
+ %59:gpr32 = exact SRA %56, 2
+ %290:gpr64 = COPY %58
+ %217:gpr64 = DADDu %290, %216
+ %218:gpr64 = DSRA %217, 18
+ %293:gpr64 = COPY %32
+ %225:acc64 = PseudoMULT %6, %59
+ %226:gpr32 = PseudoMFLO %225
+ bb.58:
+ %79:gpr32 = SRA %20, 18
+ %78:gpr64 = SLL64_64 %23
+ %24:gpr64 = DADDu %24, %78
+ %311:gpr64 = COPY %58
+ %312:gpr64 = COPY %57
+ %180:gpr32 = SLT64 %312, %311
+ BEQ %180, $zero, %bb.87, implicit-def dead $at
+ bb.86:
+ %58:gpr64 = DADDu %58, %33
+ %57:gpr64 = DADDu %57, %26
+ BNE %56, %34, %bb.58, implicit-def $at
+ bb.87:
+ %313:gpr64 = COPY %30
+ bb.96:
+ bb.97:
+ %267:gpr32 = samesign SLTu64 %271, %108
+ BNE %267, $zero, %bb.2, implicit-def dead $at
+ J %bb.1, implicit-def dead $at
\ No newline at end of file
``````````
</details>
https://github.com/llvm/llvm-project/pull/217798
More information about the llvm-branch-commits
mailing list