[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