[llvm] 6f85075 - [M68k] U/SMULd32d16 are not supposed to be communitive

Min-Yih Hsu via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 26 20:59:03 PST 2023


Author: Min-Yih Hsu
Date: 2023-12-26T20:55:22-08:00
New Revision: 6f85075ff7281be1802c9fd30758d34b67481a1e

URL: https://github.com/llvm/llvm-project/commit/6f85075ff7281be1802c9fd30758d34b67481a1e
DIFF: https://github.com/llvm/llvm-project/commit/6f85075ff7281be1802c9fd30758d34b67481a1e.diff

LOG: [M68k] U/SMULd32d16 are not supposed to be communitive

M68k only has 16-bit x 16-bit -> 32-bit variant for multiplications
taking 16-bit operands. We still define two input operands for this
class of instructions, and tie the first operand to the result value.
The problem is that the two operands have different register classes
(DR32 and DR16) hence making these instructions communitive produces
invalid MachineInstr (though the final assembly will still be correct).

Added: 
    

Modified: 
    llvm/lib/Target/M68k/M68kInstrArithmetic.td
    llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll
    llvm/test/CodeGen/M68k/Arith/umul-with-overflow.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/M68k/M68kInstrArithmetic.td b/llvm/lib/Target/M68k/M68kInstrArithmetic.td
index 7f250f4e56ef26..1f5f1e815e2bff 100644
--- a/llvm/lib/Target/M68k/M68kInstrArithmetic.td
+++ b/llvm/lib/Target/M68k/M68kInstrArithmetic.td
@@ -623,11 +623,9 @@ class MxDiMuOp_DI<string MN, bits<4> CMD, bit SIGNED = false,
 } // let Constraints
 } // Defs = [CCR]
 
-multiclass MxDiMuOp<string MN, bits<4> CMD, bit isComm = 0> {
-  let isCommutable = isComm in {
-    def "S"#NAME#"d32d16" : MxDiMuOp_DD<MN#"s", CMD, /*SIGNED*/true, MxDRD32, MxDRD16>;
-    def "U"#NAME#"d32d16" : MxDiMuOp_DD<MN#"u", CMD, /*SIGNED*/false, MxDRD32, MxDRD16>;
-  }
+multiclass MxDiMuOp<string MN, bits<4> CMD> {
+  def "S"#NAME#"d32d16" : MxDiMuOp_DD<MN#"s", CMD, /*SIGNED*/true, MxDRD32, MxDRD16>;
+  def "U"#NAME#"d32d16" : MxDiMuOp_DD<MN#"u", CMD, /*SIGNED*/false, MxDRD32, MxDRD16>;
 
   def "S"#NAME#"d32i16" : MxDiMuOp_DI<MN#"s", CMD, /*SIGNED*/true, MxDRD32, Mxi16imm>;
   def "U"#NAME#"d32i16" : MxDiMuOp_DI<MN#"u", CMD, /*SIGNED*/false, MxDRD32, Mxi16imm>;
@@ -729,7 +727,7 @@ def : Pat<(urem i16:$dst, MximmSExt16:$opd),
              MxSubRegIndex16Lo)>;
 
 
-defm MUL : MxDiMuOp<"mul", 0xC, 1>;
+defm MUL : MxDiMuOp<"mul", 0xC>;
 
 def SMULd32d32 : MxDiMuOp_DD_Long<"muls.l", MxSMul, 0x130, /*SIGNED*/true>;
 def UMULd32d32 : MxDiMuOp_DD_Long<"mulu.l", MxUMul, 0x130, /*SIGNED*/false>;

diff  --git a/llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll b/llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll
index cd9349181a6314..485cc50fbee2b2 100644
--- a/llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll
+++ b/llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll
@@ -1,6 +1,56 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s
 
+define zeroext i8 @smul_i8(i8 signext %a, i8 signext %b) nounwind ssp {
+; CHECK-LABEL: smul_i8:
+; CHECK:       ; %bb.0: ; %entry
+; CHECK-NEXT:    move.b (11,%sp), %d1
+; CHECK-NEXT:    and.l #255, %d1
+; CHECK-NEXT:    move.b (7,%sp), %d0
+; CHECK-NEXT:    and.l #255, %d0
+; CHECK-NEXT:    muls %d1, %d0
+; CHECK-NEXT:    move.b #0, %d1
+; CHECK-NEXT:    move.w %d1, %ccr
+; CHECK-NEXT:    bvs .LBB0_2
+; CHECK-NEXT:  ; %bb.1: ; %entry
+; CHECK-NEXT:    move.b #42, %d0
+; CHECK-NEXT:  .LBB0_2: ; %entry
+; CHECK-NEXT:    and.l #255, %d0
+; CHECK-NEXT:    rts
+entry:
+  %smul = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 %b)
+  %cmp = extractvalue { i8, i1 } %smul, 1
+  %smul.result = extractvalue { i8, i1 } %smul, 0
+  %X = select i1 %cmp, i8 %smul.result, i8 42
+  ret i8 %X
+}
+
+declare { i8, i1 } @llvm.smul.with.overflow.i8(i8, i8) nounwind readnone
+
+define zeroext i16 @smul_i16(i16 signext %a, i16 signext %b) nounwind ssp {
+; CHECK-LABEL: smul_i16:
+; CHECK:       ; %bb.0: ; %entry
+; CHECK-NEXT:    move.w (6,%sp), %d0
+; CHECK-NEXT:    move.w (10,%sp), %d1
+; CHECK-NEXT:    muls %d1, %d0
+; CHECK-NEXT:    move.b #0, %d1
+; CHECK-NEXT:    move.w %d1, %ccr
+; CHECK-NEXT:    bvs .LBB1_2
+; CHECK-NEXT:  ; %bb.1: ; %entry
+; CHECK-NEXT:    move.w #42, %d0
+; CHECK-NEXT:  .LBB1_2: ; %entry
+; CHECK-NEXT:    and.l #65535, %d0
+; CHECK-NEXT:    rts
+entry:
+  %smul = tail call { i16, i1 } @llvm.smul.with.overflow.i16(i16 %a, i16 %b)
+  %cmp = extractvalue { i16, i1 } %smul, 1
+  %smul.result = extractvalue { i16, i1 } %smul, 0
+  %X = select i1 %cmp, i16 %smul.result, i16 42
+  ret i16 %X
+}
+
+declare { i16, i1 } @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone
+
 declare i32 @printf(i8*, ...) nounwind
 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32)
 
@@ -12,7 +62,7 @@ define fastcc i1 @test1(i32 %v1, i32 %v2) nounwind {
 ; CHECK:       ; %bb.0: ; %entry
 ; CHECK-NEXT:    suba.l #12, %sp
 ; CHECK-NEXT:    muls.l %d1, %d0
-; CHECK-NEXT:    bvc .LBB0_1
+; CHECK-NEXT:    bvc .LBB2_1
 ; CHECK-NEXT:  ; %bb.2: ; %overflow
 ; CHECK-NEXT:    lea (no,%pc), %a0
 ; CHECK-NEXT:    move.l %a0, (%sp)
@@ -20,7 +70,7 @@ define fastcc i1 @test1(i32 %v1, i32 %v2) nounwind {
 ; CHECK-NEXT:    move.b #0, %d0
 ; CHECK-NEXT:    adda.l #12, %sp
 ; CHECK-NEXT:    rts
-; CHECK-NEXT:  .LBB0_1: ; %normal
+; CHECK-NEXT:  .LBB2_1: ; %normal
 ; CHECK-NEXT:    move.l %d0, (4,%sp)
 ; CHECK-NEXT:    lea (ok,%pc), %a0
 ; CHECK-NEXT:    move.l %a0, (%sp)
@@ -50,7 +100,7 @@ define fastcc i1 @test2(i32 %v1, i32 %v2) nounwind {
 ; CHECK-NEXT:    muls.l %d1, %d0
 ; CHECK-NEXT:    svs %d1
 ; CHECK-NEXT:    sub.b #1, %d1
-; CHECK-NEXT:    bne .LBB1_2
+; CHECK-NEXT:    bne .LBB3_2
 ; CHECK-NEXT:  ; %bb.1: ; %overflow
 ; CHECK-NEXT:    lea (no,%pc), %a0
 ; CHECK-NEXT:    move.l %a0, (%sp)
@@ -58,7 +108,7 @@ define fastcc i1 @test2(i32 %v1, i32 %v2) nounwind {
 ; CHECK-NEXT:    move.b #0, %d0
 ; CHECK-NEXT:    adda.l #12, %sp
 ; CHECK-NEXT:    rts
-; CHECK-NEXT:  .LBB1_2: ; %normal
+; CHECK-NEXT:  .LBB3_2: ; %normal
 ; CHECK-NEXT:    move.l %d0, (4,%sp)
 ; CHECK-NEXT:    lea (ok,%pc), %a0
 ; CHECK-NEXT:    move.l %a0, (%sp)

diff  --git a/llvm/test/CodeGen/M68k/Arith/umul-with-overflow.ll b/llvm/test/CodeGen/M68k/Arith/umul-with-overflow.ll
index ef7171dc386fea..1dfb959e468ce8 100644
--- a/llvm/test/CodeGen/M68k/Arith/umul-with-overflow.ll
+++ b/llvm/test/CodeGen/M68k/Arith/umul-with-overflow.ll
@@ -1,6 +1,56 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -mtriple=m68k -verify-machineinstrs | FileCheck %s
 
+define zeroext i8 @umul_i8(i8 signext %a, i8 signext %b) nounwind ssp {
+; CHECK-LABEL: umul_i8:
+; CHECK:       ; %bb.0: ; %entry
+; CHECK-NEXT:    move.b (11,%sp), %d1
+; CHECK-NEXT:    and.l #255, %d1
+; CHECK-NEXT:    move.b (7,%sp), %d0
+; CHECK-NEXT:    and.l #255, %d0
+; CHECK-NEXT:    muls %d1, %d0
+; CHECK-NEXT:    move.b #0, %d1
+; CHECK-NEXT:    move.w %d1, %ccr
+; CHECK-NEXT:    bvs .LBB0_2
+; CHECK-NEXT:  ; %bb.1: ; %entry
+; CHECK-NEXT:    move.b #42, %d0
+; CHECK-NEXT:  .LBB0_2: ; %entry
+; CHECK-NEXT:    and.l #255, %d0
+; CHECK-NEXT:    rts
+entry:
+  %umul = tail call { i8, i1 } @llvm.umul.with.overflow.i8(i8 %a, i8 %b)
+  %cmp = extractvalue { i8, i1 } %umul, 1
+  %umul.result = extractvalue { i8, i1 } %umul, 0
+  %X = select i1 %cmp, i8 %umul.result, i8 42
+  ret i8 %X
+}
+
+declare { i8, i1 } @llvm.umul.with.overflow.i8(i8, i8) nounwind readnone
+
+define zeroext i16 @umul_i16(i16 signext %a, i16 signext %b) nounwind ssp {
+; CHECK-LABEL: umul_i16:
+; CHECK:       ; %bb.0: ; %entry
+; CHECK-NEXT:    move.w (6,%sp), %d0
+; CHECK-NEXT:    move.w (10,%sp), %d1
+; CHECK-NEXT:    muls %d1, %d0
+; CHECK-NEXT:    move.b #0, %d1
+; CHECK-NEXT:    move.w %d1, %ccr
+; CHECK-NEXT:    bvs .LBB1_2
+; CHECK-NEXT:  ; %bb.1: ; %entry
+; CHECK-NEXT:    move.w #42, %d0
+; CHECK-NEXT:  .LBB1_2: ; %entry
+; CHECK-NEXT:    and.l #65535, %d0
+; CHECK-NEXT:    rts
+entry:
+  %umul = tail call { i16, i1 } @llvm.umul.with.overflow.i16(i16 %a, i16 %b)
+  %cmp = extractvalue { i16, i1 } %umul, 1
+  %umul.result = extractvalue { i16, i1 } %umul, 0
+  %X = select i1 %cmp, i16 %umul.result, i16 42
+  ret i16 %X
+}
+
+declare { i16, i1 } @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone
+
 declare {i32, i1} @llvm.umul.with.overflow.i32(i32 %a, i32 %b)
 
 define i1 @a(i32 %x)  nounwind {


        


More information about the llvm-commits mailing list