Skip to content

[Mips][MSA] Lower vector fabs to BCLRI - #228532

Merged
FlyGoat merged 1 commit into
llvm:mainfrom
FlyGoat:fix-mips-msa-fabs
Oct 3, 2026
Merged

FlyGoat merged 1 commit into
llvm:mainfrom
FlyGoat:fix-mips-msa-fabs

Conversation

@FlyGoat

@FlyGoat FlyGoat commented Oct 2, 2026

Copy link
Copy Markdown
Member

FMAX_A selects an original operand by magnitude and preserves its sign, so fmax_a(x, x) does not implement fabs. Expand FABS_W and FABS_D to clear bit 31 and bit 63 with BCLRI, and update their scheduling to match the bit-clear instructions.

Fixes #228384.

@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-backend-mips

Author: Jiaxun Yang (FlyGoat)

Changes

FMAX_A selects an original operand by magnitude and preserves its sign, so fmax_a(x, x) does not implement fabs. Expand FABS_W and FABS_D to clear bit 31 and bit 63 with BCLRI, and update their scheduling to match the bit-clear instructions.

Fixes #228384.


Full diff: https://github.com/llvm/llvm-project/pull/228532.diff

7 Files Affected:

  • (modified) llvm/lib/Target/Mips/MipsMSAInstrInfo.td (+2-4)
  • (modified) llvm/lib/Target/Mips/MipsScheduleGeneric.td (+1-1)
  • (modified) llvm/lib/Target/Mips/MipsScheduleI6400.td (+2-2)
  • (modified) llvm/lib/Target/Mips/MipsScheduleP5600.td (+1-1)
  • (modified) llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fabs_vec.ll (+2-2)
  • (modified) llvm/test/CodeGen/Mips/msa/arithmetic_float.ll (+2-2)
  • (modified) llvm/test/CodeGen/Mips/msa/buildvector-undef-loop.ll (+1-1)
diff --git a/llvm/lib/Target/Mips/MipsMSAInstrInfo.td b/llvm/lib/Target/Mips/MipsMSAInstrInfo.td
index 3ecb079fbcdede..2a6357d9f15d9e 100644
--- a/llvm/lib/Target/Mips/MipsMSAInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsMSAInstrInfo.td
@@ -3465,11 +3465,9 @@ class MSA_FABS_PSEUDO_DESC_BASE<RegisterOperand ROWD,
             [(set ROWD:$wd, (fabs ROWS:$ws))]>;
 
 def FABS_W : MSA_FABS_PSEUDO_DESC_BASE<MSA128WOpnd>,
-             PseudoInstExpansion<(FMAX_A_W MSA128WOpnd:$wd, MSA128WOpnd:$ws,
-                                           MSA128WOpnd:$ws)>;
+             PseudoInstExpansion<(BCLRI_W MSA128WOpnd:$wd, MSA128WOpnd:$ws, 31)>;
 def FABS_D : MSA_FABS_PSEUDO_DESC_BASE<MSA128DOpnd>,
-             PseudoInstExpansion<(FMAX_A_D MSA128DOpnd:$wd, MSA128DOpnd:$ws,
-                                           MSA128DOpnd:$ws)>;
+             PseudoInstExpansion<(BCLRI_D MSA128DOpnd:$wd, MSA128DOpnd:$ws, 63)>;
 
 class MSABitconvertPat<ValueType DstVT, ValueType SrcVT,
                        RegisterClass DstRC, list<Predicate> preds = [HasMSA]> :
diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td
index ec0c0d03ae4ee5..d2526ee238f72f 100644
--- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td
+++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td
@@ -1449,6 +1449,7 @@ def : InstRW<[GenericWriteMSAShortInt], (instregex "^INSERT_[BHWD]$")>;
 def : InstRW<[GenericWriteMSAShortInt], (instregex "^(SLD|SLDI)_[BHWD]$")>;
 def : InstRW<[GenericWriteMSAShortInt], (instregex "^(BSET|BSETI)_[BHWD]$")>;
 def : InstRW<[GenericWriteMSAShortInt], (instregex "^(BCLR|BCLRI)_[BHWD]$")>;
+def : InstRW<[GenericWriteMSAShortInt], (instregex "^FABS_(W|D)$")>;
 def : InstRW<[GenericWriteMSAShortInt], (instregex "^(BNEG|BNEGI)_[BHWD]$")>;
 def : InstRW<[GenericWriteMSAShortInt], (instregex "^(BSEL_V|BSELI_B)$")>;
 def : InstRW<[GenericWriteMSAShortInt], (instregex "^BMN*Z.*$")>;
@@ -1508,7 +1509,6 @@ def : InstRW<[GenericWriteFPUS], (instregex "^FCULE_(W|D)$")>;
 def : InstRW<[GenericWriteFPUS], (instregex "^FCULT_(W|D)$")>;
 def : InstRW<[GenericWriteFPUS], (instregex "^FCUNE_(W|D)$")>;
 def : InstRW<[GenericWriteFPUS], (instregex "^FCUN_(W|D)$")>;
-def : InstRW<[GenericWriteFPUS], (instregex "^FABS_(W|D)$")>;
 def : InstRW<[GenericWriteFPUS], (instregex "^FFINT_(U|S)_(W|D)$")>;
 def : InstRW<[GenericWriteFPUS], (instregex "^FFQL_(W|D)$")>;
 def : InstRW<[GenericWriteFPUS], (instregex "^FFQR_(W|D)$")>;
diff --git a/llvm/lib/Target/Mips/MipsScheduleI6400.td b/llvm/lib/Target/Mips/MipsScheduleI6400.td
index 342e7ac31eb5a6..ec2848dbe53732 100644
--- a/llvm/lib/Target/Mips/MipsScheduleI6400.td
+++ b/llvm/lib/Target/Mips/MipsScheduleI6400.td
@@ -246,7 +246,7 @@ let SchedModel = MipsI6400Model in {
                    NLZC_B, NLZC_H, NLZC_W, NLZC_D, BNEG_B, BNEG_H, BNEG_W,
                    BNEG_D, BNEGI_B, BNEGI_H, BNEGI_W, BNEGI_D, BCLR_B, BCLR_H,
                    BCLR_W, BCLR_D, BCLRI_B, BCLRI_H, BCLRI_W, BCLRI_D, SHF_B,
-                   SHF_H, SHF_W)>;
+                   SHF_H, SHF_W, FABS_W, FABS_D)>;
 
   def I6400MSAShortLogic : SchedWriteRes<[I6400FPUShort]> {
     let ReleaseAtCycles = [2];
@@ -307,7 +307,7 @@ let SchedModel = MipsI6400Model in {
   }
   def : InstRW<[I6400MSAShortFloat], (instrs FMAX_W, FMAX_D, FMAX_A_W, FMAX_A_D,
                                          FMIN_W, FMIN_D, FMIN_A_W, FMIN_A_D,
-                                         FCLASS_W, FCLASS_D, FABS_D, FABS_W,
+                                         FCLASS_W, FCLASS_D,
 					 FABS_D32, FABS_D64)>;
   def I6400MSAFloatCompare : SchedWriteRes<[I6400FPUShort]> {
     let Latency = 2;
diff --git a/llvm/lib/Target/Mips/MipsScheduleP5600.td b/llvm/lib/Target/Mips/MipsScheduleP5600.td
index dce05df0f609a0..5ac235766f30ff 100644
--- a/llvm/lib/Target/Mips/MipsScheduleP5600.td
+++ b/llvm/lib/Target/Mips/MipsScheduleP5600.td
@@ -298,6 +298,7 @@ def : InstRW<[P5600WriteMSAShortInt], (instregex "^INSERT_[BHWD]$")>;
 def : InstRW<[P5600WriteMSAShortInt], (instregex "^(SLD|SLDI)_[BHWD]$")>;
 def : InstRW<[P5600WriteMSAShortInt], (instregex "^(BSET|BSETI)_[BHWD]$")>;
 def : InstRW<[P5600WriteMSAShortInt], (instregex "^(BCLR|BCLRI)_[BHWD]$")>;
+def : InstRW<[P5600WriteMSAShortInt], (instregex "^FABS_(W|D)$")>;
 def : InstRW<[P5600WriteMSAShortInt], (instregex "^(BNEG|BNEGI)_[BHWD]$")>;
 def : InstRW<[P5600WriteMSAShortInt], (instregex "^(BSEL_V|BSELI_B)$")>;
 def : InstRW<[P5600WriteMSAShortInt], (instregex "^BMN*Z.*$")>;
@@ -386,7 +387,6 @@ def : InstRW<[P5600WriteFPUS], (instregex "^FCULE_(W|D)$")>;
 def : InstRW<[P5600WriteFPUS], (instregex "^FCULT_(W|D)$")>;
 def : InstRW<[P5600WriteFPUS], (instregex "^FCUNE_(W|D)$")>;
 def : InstRW<[P5600WriteFPUS], (instregex "^FCUN_(W|D)$")>;
-def : InstRW<[P5600WriteFPUS], (instregex "^FABS_(W|D)$")>;
 def : InstRW<[P5600WriteFPUS], (instregex "^FFINT_(U|S)_(W|D)$")>;
 def : InstRW<[P5600WriteFPUS], (instregex "^FFQL_(W|D)$")>;
 def : InstRW<[P5600WriteFPUS], (instregex "^FFQR_(W|D)$")>;
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fabs_vec.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fabs_vec.ll
index 5a2715ce5dd097..15c534b734fb22 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fabs_vec.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fabs_vec.ll
@@ -6,7 +6,7 @@ define void @fabs_v4f32(ptr %a, ptr %c) {
 ; P5600-LABEL: fabs_v4f32:
 ; P5600:       # %bb.0: # %entry
 ; P5600-NEXT:    ld.w $w0, 0($4)
-; P5600-NEXT:    fmax_a.w $w0, $w0, $w0
+; P5600-NEXT:    bclri.w $w0, $w0, 31
 ; P5600-NEXT:    st.w $w0, 0($5)
 ; P5600-NEXT:    jr $ra
 ; P5600-NEXT:    nop
@@ -22,7 +22,7 @@ define void @fabs_v2f64(ptr %a, ptr %c) {
 ; P5600-LABEL: fabs_v2f64:
 ; P5600:       # %bb.0: # %entry
 ; P5600-NEXT:    ld.d $w0, 0($4)
-; P5600-NEXT:    fmax_a.d $w0, $w0, $w0
+; P5600-NEXT:    bclri.d $w0, $w0, 63
 ; P5600-NEXT:    st.d $w0, 0($5)
 ; P5600-NEXT:    jr $ra
 ; P5600-NEXT:    nop
diff --git a/llvm/test/CodeGen/Mips/msa/arithmetic_float.ll b/llvm/test/CodeGen/Mips/msa/arithmetic_float.ll
index b97e0539fcf699..cf34550c32c638 100644
--- a/llvm/test/CodeGen/Mips/msa/arithmetic_float.ll
+++ b/llvm/test/CodeGen/Mips/msa/arithmetic_float.ll
@@ -217,7 +217,7 @@ define void @fabs_v4f32(ptr %c, ptr %a) nounwind {
   %1 = load <4 x float>, ptr %a
   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
   %2 = tail call <4 x float> @llvm.fabs.v4f32 (<4 x float> %1)
-  ; CHECK-DAG: fmax_a.w [[R3:\$w[0-9]+]], [[R1]], [[R1]]
+  ; CHECK-DAG: bclri.w [[R3:\$w[0-9]+]], [[R1]], 31
   store <4 x float> %2, ptr %c
   ; CHECK-DAG: st.w [[R3]], 0($4)
 
@@ -231,7 +231,7 @@ define void @fabs_v2f64(ptr %c, ptr %a) nounwind {
   %1 = load <2 x double>, ptr %a
   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
   %2 = tail call <2 x double> @llvm.fabs.v2f64 (<2 x double> %1)
-  ; CHECK-DAG: fmax_a.d [[R3:\$w[0-9]+]], [[R1]], [[R1]]
+  ; CHECK-DAG: bclri.d [[R3:\$w[0-9]+]], [[R1]], 63
   store <2 x double> %2, ptr %c
   ; CHECK-DAG: st.d [[R3]], 0($4)
 
diff --git a/llvm/test/CodeGen/Mips/msa/buildvector-undef-loop.ll b/llvm/test/CodeGen/Mips/msa/buildvector-undef-loop.ll
index 80fa4049d0f10b..8921bca8cc6e5e 100644
--- a/llvm/test/CodeGen/Mips/msa/buildvector-undef-loop.ll
+++ b/llvm/test/CodeGen/Mips/msa/buildvector-undef-loop.ll
@@ -14,7 +14,7 @@ define void @nonsplatvalue_v4f32(float %a, float %b, float %c, float %d) nounwin
 ; MIPS64R5-NEXT:    insve.w $w0[1], $w13[0]
 ; MIPS64R5-NEXT:    insve.w $w0[2], $w14[0]
 ; MIPS64R5-NEXT:    insve.w $w0[3], $w15[0]
-; MIPS64R5-NEXT:    fmax_a.w $w0, $w0, $w0
+; MIPS64R5-NEXT:    bclri.w $w0, $w0, 31
 ; MIPS64R5-NEXT:    lui $1, %highest(v4f32)
 ; MIPS64R5-NEXT:    daddiu $1, $1, %higher(v4f32)
 ; MIPS64R5-NEXT:    dsll $1, $1, 16

@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-llvm-globalisel

Author: Jiaxun Yang (FlyGoat)

Changes

FMAX_A selects an original operand by magnitude and preserves its sign, so fmax_a(x, x) does not implement fabs. Expand FABS_W and FABS_D to clear bit 31 and bit 63 with BCLRI, and update their scheduling to match the bit-clear instructions.

Fixes #228384.


Full diff: https://github.com/llvm/llvm-project/pull/228532.diff

7 Files Affected:

  • (modified) llvm/lib/Target/Mips/MipsMSAInstrInfo.td (+2-4)
  • (modified) llvm/lib/Target/Mips/MipsScheduleGeneric.td (+1-1)
  • (modified) llvm/lib/Target/Mips/MipsScheduleI6400.td (+2-2)
  • (modified) llvm/lib/Target/Mips/MipsScheduleP5600.td (+1-1)
  • (modified) llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fabs_vec.ll (+2-2)
  • (modified) llvm/test/CodeGen/Mips/msa/arithmetic_float.ll (+2-2)
  • (modified) llvm/test/CodeGen/Mips/msa/buildvector-undef-loop.ll (+1-1)
diff --git a/llvm/lib/Target/Mips/MipsMSAInstrInfo.td b/llvm/lib/Target/Mips/MipsMSAInstrInfo.td
index 3ecb079fbcdede..2a6357d9f15d9e 100644
--- a/llvm/lib/Target/Mips/MipsMSAInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsMSAInstrInfo.td
@@ -3465,11 +3465,9 @@ class MSA_FABS_PSEUDO_DESC_BASE<RegisterOperand ROWD,
             [(set ROWD:$wd, (fabs ROWS:$ws))]>;
 
 def FABS_W : MSA_FABS_PSEUDO_DESC_BASE<MSA128WOpnd>,
-             PseudoInstExpansion<(FMAX_A_W MSA128WOpnd:$wd, MSA128WOpnd:$ws,
-                                           MSA128WOpnd:$ws)>;
+             PseudoInstExpansion<(BCLRI_W MSA128WOpnd:$wd, MSA128WOpnd:$ws, 31)>;
 def FABS_D : MSA_FABS_PSEUDO_DESC_BASE<MSA128DOpnd>,
-             PseudoInstExpansion<(FMAX_A_D MSA128DOpnd:$wd, MSA128DOpnd:$ws,
-                                           MSA128DOpnd:$ws)>;
+             PseudoInstExpansion<(BCLRI_D MSA128DOpnd:$wd, MSA128DOpnd:$ws, 63)>;
 
 class MSABitconvertPat<ValueType DstVT, ValueType SrcVT,
                        RegisterClass DstRC, list<Predicate> preds = [HasMSA]> :
diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td
index ec0c0d03ae4ee5..d2526ee238f72f 100644
--- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td
+++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td
@@ -1449,6 +1449,7 @@ def : InstRW<[GenericWriteMSAShortInt], (instregex "^INSERT_[BHWD]$")>;
 def : InstRW<[GenericWriteMSAShortInt], (instregex "^(SLD|SLDI)_[BHWD]$")>;
 def : InstRW<[GenericWriteMSAShortInt], (instregex "^(BSET|BSETI)_[BHWD]$")>;
 def : InstRW<[GenericWriteMSAShortInt], (instregex "^(BCLR|BCLRI)_[BHWD]$")>;
+def : InstRW<[GenericWriteMSAShortInt], (instregex "^FABS_(W|D)$")>;
 def : InstRW<[GenericWriteMSAShortInt], (instregex "^(BNEG|BNEGI)_[BHWD]$")>;
 def : InstRW<[GenericWriteMSAShortInt], (instregex "^(BSEL_V|BSELI_B)$")>;
 def : InstRW<[GenericWriteMSAShortInt], (instregex "^BMN*Z.*$")>;
@@ -1508,7 +1509,6 @@ def : InstRW<[GenericWriteFPUS], (instregex "^FCULE_(W|D)$")>;
 def : InstRW<[GenericWriteFPUS], (instregex "^FCULT_(W|D)$")>;
 def : InstRW<[GenericWriteFPUS], (instregex "^FCUNE_(W|D)$")>;
 def : InstRW<[GenericWriteFPUS], (instregex "^FCUN_(W|D)$")>;
-def : InstRW<[GenericWriteFPUS], (instregex "^FABS_(W|D)$")>;
 def : InstRW<[GenericWriteFPUS], (instregex "^FFINT_(U|S)_(W|D)$")>;
 def : InstRW<[GenericWriteFPUS], (instregex "^FFQL_(W|D)$")>;
 def : InstRW<[GenericWriteFPUS], (instregex "^FFQR_(W|D)$")>;
diff --git a/llvm/lib/Target/Mips/MipsScheduleI6400.td b/llvm/lib/Target/Mips/MipsScheduleI6400.td
index 342e7ac31eb5a6..ec2848dbe53732 100644
--- a/llvm/lib/Target/Mips/MipsScheduleI6400.td
+++ b/llvm/lib/Target/Mips/MipsScheduleI6400.td
@@ -246,7 +246,7 @@ let SchedModel = MipsI6400Model in {
                    NLZC_B, NLZC_H, NLZC_W, NLZC_D, BNEG_B, BNEG_H, BNEG_W,
                    BNEG_D, BNEGI_B, BNEGI_H, BNEGI_W, BNEGI_D, BCLR_B, BCLR_H,
                    BCLR_W, BCLR_D, BCLRI_B, BCLRI_H, BCLRI_W, BCLRI_D, SHF_B,
-                   SHF_H, SHF_W)>;
+                   SHF_H, SHF_W, FABS_W, FABS_D)>;
 
   def I6400MSAShortLogic : SchedWriteRes<[I6400FPUShort]> {
     let ReleaseAtCycles = [2];
@@ -307,7 +307,7 @@ let SchedModel = MipsI6400Model in {
   }
   def : InstRW<[I6400MSAShortFloat], (instrs FMAX_W, FMAX_D, FMAX_A_W, FMAX_A_D,
                                          FMIN_W, FMIN_D, FMIN_A_W, FMIN_A_D,
-                                         FCLASS_W, FCLASS_D, FABS_D, FABS_W,
+                                         FCLASS_W, FCLASS_D,
 					 FABS_D32, FABS_D64)>;
   def I6400MSAFloatCompare : SchedWriteRes<[I6400FPUShort]> {
     let Latency = 2;
diff --git a/llvm/lib/Target/Mips/MipsScheduleP5600.td b/llvm/lib/Target/Mips/MipsScheduleP5600.td
index dce05df0f609a0..5ac235766f30ff 100644
--- a/llvm/lib/Target/Mips/MipsScheduleP5600.td
+++ b/llvm/lib/Target/Mips/MipsScheduleP5600.td
@@ -298,6 +298,7 @@ def : InstRW<[P5600WriteMSAShortInt], (instregex "^INSERT_[BHWD]$")>;
 def : InstRW<[P5600WriteMSAShortInt], (instregex "^(SLD|SLDI)_[BHWD]$")>;
 def : InstRW<[P5600WriteMSAShortInt], (instregex "^(BSET|BSETI)_[BHWD]$")>;
 def : InstRW<[P5600WriteMSAShortInt], (instregex "^(BCLR|BCLRI)_[BHWD]$")>;
+def : InstRW<[P5600WriteMSAShortInt], (instregex "^FABS_(W|D)$")>;
 def : InstRW<[P5600WriteMSAShortInt], (instregex "^(BNEG|BNEGI)_[BHWD]$")>;
 def : InstRW<[P5600WriteMSAShortInt], (instregex "^(BSEL_V|BSELI_B)$")>;
 def : InstRW<[P5600WriteMSAShortInt], (instregex "^BMN*Z.*$")>;
@@ -386,7 +387,6 @@ def : InstRW<[P5600WriteFPUS], (instregex "^FCULE_(W|D)$")>;
 def : InstRW<[P5600WriteFPUS], (instregex "^FCULT_(W|D)$")>;
 def : InstRW<[P5600WriteFPUS], (instregex "^FCUNE_(W|D)$")>;
 def : InstRW<[P5600WriteFPUS], (instregex "^FCUN_(W|D)$")>;
-def : InstRW<[P5600WriteFPUS], (instregex "^FABS_(W|D)$")>;
 def : InstRW<[P5600WriteFPUS], (instregex "^FFINT_(U|S)_(W|D)$")>;
 def : InstRW<[P5600WriteFPUS], (instregex "^FFQL_(W|D)$")>;
 def : InstRW<[P5600WriteFPUS], (instregex "^FFQR_(W|D)$")>;
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fabs_vec.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fabs_vec.ll
index 5a2715ce5dd097..15c534b734fb22 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fabs_vec.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fabs_vec.ll
@@ -6,7 +6,7 @@ define void @fabs_v4f32(ptr %a, ptr %c) {
 ; P5600-LABEL: fabs_v4f32:
 ; P5600:       # %bb.0: # %entry
 ; P5600-NEXT:    ld.w $w0, 0($4)
-; P5600-NEXT:    fmax_a.w $w0, $w0, $w0
+; P5600-NEXT:    bclri.w $w0, $w0, 31
 ; P5600-NEXT:    st.w $w0, 0($5)
 ; P5600-NEXT:    jr $ra
 ; P5600-NEXT:    nop
@@ -22,7 +22,7 @@ define void @fabs_v2f64(ptr %a, ptr %c) {
 ; P5600-LABEL: fabs_v2f64:
 ; P5600:       # %bb.0: # %entry
 ; P5600-NEXT:    ld.d $w0, 0($4)
-; P5600-NEXT:    fmax_a.d $w0, $w0, $w0
+; P5600-NEXT:    bclri.d $w0, $w0, 63
 ; P5600-NEXT:    st.d $w0, 0($5)
 ; P5600-NEXT:    jr $ra
 ; P5600-NEXT:    nop
diff --git a/llvm/test/CodeGen/Mips/msa/arithmetic_float.ll b/llvm/test/CodeGen/Mips/msa/arithmetic_float.ll
index b97e0539fcf699..cf34550c32c638 100644
--- a/llvm/test/CodeGen/Mips/msa/arithmetic_float.ll
+++ b/llvm/test/CodeGen/Mips/msa/arithmetic_float.ll
@@ -217,7 +217,7 @@ define void @fabs_v4f32(ptr %c, ptr %a) nounwind {
   %1 = load <4 x float>, ptr %a
   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
   %2 = tail call <4 x float> @llvm.fabs.v4f32 (<4 x float> %1)
-  ; CHECK-DAG: fmax_a.w [[R3:\$w[0-9]+]], [[R1]], [[R1]]
+  ; CHECK-DAG: bclri.w [[R3:\$w[0-9]+]], [[R1]], 31
   store <4 x float> %2, ptr %c
   ; CHECK-DAG: st.w [[R3]], 0($4)
 
@@ -231,7 +231,7 @@ define void @fabs_v2f64(ptr %c, ptr %a) nounwind {
   %1 = load <2 x double>, ptr %a
   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
   %2 = tail call <2 x double> @llvm.fabs.v2f64 (<2 x double> %1)
-  ; CHECK-DAG: fmax_a.d [[R3:\$w[0-9]+]], [[R1]], [[R1]]
+  ; CHECK-DAG: bclri.d [[R3:\$w[0-9]+]], [[R1]], 63
   store <2 x double> %2, ptr %c
   ; CHECK-DAG: st.d [[R3]], 0($4)
 
diff --git a/llvm/test/CodeGen/Mips/msa/buildvector-undef-loop.ll b/llvm/test/CodeGen/Mips/msa/buildvector-undef-loop.ll
index 80fa4049d0f10b..8921bca8cc6e5e 100644
--- a/llvm/test/CodeGen/Mips/msa/buildvector-undef-loop.ll
+++ b/llvm/test/CodeGen/Mips/msa/buildvector-undef-loop.ll
@@ -14,7 +14,7 @@ define void @nonsplatvalue_v4f32(float %a, float %b, float %c, float %d) nounwin
 ; MIPS64R5-NEXT:    insve.w $w0[1], $w13[0]
 ; MIPS64R5-NEXT:    insve.w $w0[2], $w14[0]
 ; MIPS64R5-NEXT:    insve.w $w0[3], $w15[0]
-; MIPS64R5-NEXT:    fmax_a.w $w0, $w0, $w0
+; MIPS64R5-NEXT:    bclri.w $w0, $w0, 31
 ; MIPS64R5-NEXT:    lui $1, %highest(v4f32)
 ; MIPS64R5-NEXT:    daddiu $1, $1, %higher(v4f32)
 ; MIPS64R5-NEXT:    dsll $1, $1, 16

@FlyGoat
FlyGoat force-pushed the fix-mips-msa-fabs branch from 35deda3 to f293cd0 Compare October 2, 2026 20:08

@arsenm arsenm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using fmax is certainly wrong

@@ -3465,11 +3465,9 @@ class MSA_FABS_PSEUDO_DESC_BASE<RegisterOperand ROWD,
[(set ROWD:$wd, (fabs ROWS:$ws))]>;

def FABS_W : MSA_FABS_PSEUDO_DESC_BASE<MSA128WOpnd>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what the point of this pseudo instruction is, can't you directly select this

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that’s so wired.

I’m looking into a minimal fix that can be backported so I’ll leave it as is for now.

Will do a cleanup follow up.

FMAX_A selects an original operand by magnitude and preserves its sign, so fmax_a(x, x) does not implement fabs. Expand FABS_W and FABS_D to clear bit 31 and bit 63 with BCLRI, and update their scheduling to match the bit-clear instructions.

Fixes llvm#228384.
@FlyGoat
FlyGoat force-pushed the fix-mips-msa-fabs branch from f293cd0 to db2b81c Compare October 3, 2026 11:38
@FlyGoat
FlyGoat enabled auto-merge (squash) October 3, 2026 11:38
@FlyGoat
FlyGoat disabled auto-merge October 3, 2026 11:53
@FlyGoat
FlyGoat enabled auto-merge (squash) October 3, 2026 11:55
@FlyGoat
FlyGoat merged commit 21970fa into llvm:main Oct 3, 2026
10 of 11 checks passed
tru pushed a commit that referenced this pull request Oct 5, 2026
FMAX_A selects an original operand by magnitude and preserves its sign,
so fmax_a(x, x) does not implement fabs. Expand FABS_W and FABS_D to
clear bit 31 and bit 63 with BCLRI, and update their scheduling to match
the bit-clear instructions.

Fixes #228384.

(cherry picked from commit 21970fa)
@llvm-ci

llvm-ci commented Oct 6, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder ml-opt-devrel-x86-64 running on ml-opt-devrel-x86-64-b1 while building llvm at step 4 "cmake-configure".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/175/builds/4982

Here is the relevant piece of the build log for the reference
Step 4 (cmake-configure) failure: cmake (failure)
...
-- Registering Bye as a pass plugin (static build: OFF)
-- Failed to find LLVM FileCheck
-- Google Benchmark version: v1.9.5, normalized to 1.9.5
-- Looking for shm_open in rt
-- Looking for shm_open in rt - found
-- Performing Test HAVE_CXX_FLAG_WALL
-- Performing Test HAVE_CXX_FLAG_WALL - Success
-- Performing Test HAVE_CXX_FLAG_WEXTRA
-- Performing Test HAVE_CXX_FLAG_WEXTRA - Success
-- Performing Test HAVE_CXX_FLAG_WSHADOW
-- Performing Test HAVE_CXX_FLAG_WSHADOW - Success
-- Performing Test HAVE_CXX_FLAG_WFLOAT_EQUAL
-- Performing Test HAVE_CXX_FLAG_WFLOAT_EQUAL - Success
-- Performing Test HAVE_CXX_FLAG_WOLD_STYLE_CAST
-- Performing Test HAVE_CXX_FLAG_WOLD_STYLE_CAST - Success
-- Performing Test HAVE_CXX_FLAG_WCONVERSION
-- Performing Test HAVE_CXX_FLAG_WCONVERSION - Success
-- Performing Test HAVE_CXX_FLAG_WFORMAT_2
-- Performing Test HAVE_CXX_FLAG_WFORMAT_2 - Success
-- Performing Test HAVE_CXX_FLAG_WSUGGEST_OVERRIDE
-- Performing Test HAVE_CXX_FLAG_WSUGGEST_OVERRIDE - Success
-- Performing Test HAVE_CXX_FLAG_PEDANTIC
-- Performing Test HAVE_CXX_FLAG_PEDANTIC - Success
-- Performing Test HAVE_CXX_FLAG_PEDANTIC_ERRORS
-- Performing Test HAVE_CXX_FLAG_PEDANTIC_ERRORS - Success
-- Performing Test HAVE_CXX_FLAG_WSHORTEN_64_TO_32
-- Performing Test HAVE_CXX_FLAG_WSHORTEN_64_TO_32 - Success
-- Performing Test HAVE_CXX_FLAG_FSTRICT_ALIASING
-- Performing Test HAVE_CXX_FLAG_FSTRICT_ALIASING - Success
-- Performing Test HAVE_CXX_FLAG_WNO_DEPRECATED_DECLARATIONS
-- Performing Test HAVE_CXX_FLAG_WNO_DEPRECATED_DECLARATIONS - Success
-- Performing Test HAVE_CXX_FLAG_FNO_EXCEPTIONS
-- Performing Test HAVE_CXX_FLAG_FNO_EXCEPTIONS - Success
-- Performing Test HAVE_CXX_FLAG_WSTRICT_ALIASING
-- Performing Test HAVE_CXX_FLAG_WSTRICT_ALIASING - Success
-- Performing Test HAVE_CXX_FLAG_WTHREAD_SAFETY
-- Performing Test HAVE_CXX_FLAG_WTHREAD_SAFETY - Success
-- Enabling additional flags: -DINCLUDE_DIRECTORIES=/b/ml-opt-devrel-x86-64-b1/llvm-project/third-party/benchmark/include
-- Performing Test THREAD_SAFETY_ATTRIBUTES -- success
-- Performing Test HAVE_CXX_FLAG_COVERAGE
-- Performing Test HAVE_CXX_FLAG_COVERAGE - Success
CMake Warning at /b/ml-opt-devrel-x86-64-b1/llvm-project/third-party/benchmark/CMakeLists.txt:329 (message):
  Using std::regex with exceptions disabled is not fully supported


-- Performing Test STEADY_CLOCK -- success
-- Performing Test PTHREAD_AFFINITY -- success
-- Configuring incomplete, errors occurred!
See also "/b/ml-opt-devrel-x86-64-b1/build/CMakeFiles/CMakeOutput.log".
See also "/b/ml-opt-devrel-x86-64-b1/build/CMakeFiles/CMakeError.log".

gandhi56 pushed a commit that referenced this pull request Oct 7, 2026
FMAX_A selects an original operand by magnitude and preserves its sign,
so fmax_a(x, x) does not implement fabs. Expand FABS_W and FABS_D to
clear bit 31 and bit 63 with BCLRI, and update their scheduling to match
the bit-clear instructions.

Fixes #228384.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Mips][MSA] Vector fabs incorrectly lowers to fmax_a(x, x)

3 participants