]> granicus.if.org Git - llvm/commitdiff
[ARM][GlobalISel] Legalize narrow scalar ops by widening
authorDiana Picus <diana.picus@linaro.org>
Thu, 11 May 2017 09:45:57 +0000 (09:45 +0000)
committerDiana Picus <diana.picus@linaro.org>
Thu, 11 May 2017 09:45:57 +0000 (09:45 +0000)
This is the same as r292827 for AArch64: we widen 8- and 16-bit ADD, SUB
and MUL to 32 bits since we only have TableGen patterns for 32 bits.
See the commit message for r292827 for more details.

At this point we could just remove some of the tests for regbankselect
and instruction-select, since we're not going to see any narrow
operations at those levels anymore. Instead I decided to update them
with G_ANYEXT/G_TRUNC operations, so we can validate the full sequences
generated by the legalizer.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302782 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMLegalizerInfo.cpp
test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir
test/CodeGen/ARM/GlobalISel/arm-legalizer.mir
test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir

index 9b86030fdd2956fde37e8b58bbbc73c08caa3f70..5bf6c7aed6b82c49835ed36a62d9fede69ebc7d7 100644 (file)
@@ -45,9 +45,11 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
     setAction({Op, 1, p0}, Legal);
   }
 
-  for (unsigned Op : {G_ADD, G_SUB, G_MUL})
-    for (auto Ty : {s1, s8, s16, s32})
-      setAction({Op, Ty}, Legal);
+  for (unsigned Op : {G_ADD, G_SUB, G_MUL}) {
+    for (auto Ty : {s1, s8, s16})
+      setAction({Op, Ty}, WidenScalar);
+    setAction({Op, s32}, Legal);
+  }
 
   for (unsigned Op : {G_SDIV, G_UDIV}) {
     for (auto Ty : {s8, s16})
index a4c5477e543976fecb816a5a3f9bf3e4bb81f640..72c3b715d36e8e9f9cd59344db04beebd3141b17 100644 (file)
@@ -241,9 +241,15 @@ registers:
   - { id: 0, class: gprb }
   - { id: 1, class: gprb }
   - { id: 2, class: gprb }
+  - { id: 3, class: gprb }
+  - { id: 4, class: gprb }
+  - { id: 5, class: gprb }
 # CHECK-DAG: id: 0, class: gpr
 # CHECK-DAG: id: 1, class: gpr
 # CHECK-DAG: id: 2, class: gpr
+# CHECK-DAG: id: 3, class: gpr
+# CHECK-DAG: id: 4, class: gpr
+# CHECK-DAG: id: 5, class: gpr
 body:             |
   bb.0:
     liveins: %r0, %r1
@@ -254,11 +260,20 @@ body:             |
     %1(s8) = COPY %r1
     ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1
 
-    %2(s8) = G_ADD %0, %1
-    ; CHECK: [[VREGSUM:%[0-9]+]] = ADDrr [[VREGX]], [[VREGY]], 14, _, _
+    %2(s32) = G_ANYEXT %0(s8)
+    ; CHECK: [[VREGXEXT:%[0-9]+]] = COPY [[VREGX]]
 
-    %r0 = COPY %2(s8)
-    ; CHECK: %r0 = COPY [[VREGSUM]]
+    %3(s32) = G_ANYEXT %1(s8)
+    ; CHECK: [[VREGYEXT:%[0-9]+]] = COPY [[VREGY]]
+
+    %4(s32) = G_ADD %2, %3
+    ; CHECK: [[VREGSUM:%[0-9]+]] = ADDrr [[VREGXEXT]], [[VREGYEXT]], 14, _, _
+
+    %5(s8) = G_TRUNC %4(s32)
+    ; CHECK: [[VREGSUMTR:%[0-9]+]] = COPY [[VREGSUM]]
+
+    %r0 = COPY %5(s8)
+    ; CHECK: %r0 = COPY [[VREGSUMTR]]
 
     BX_RET 14, _, implicit %r0
     ; CHECK: BX_RET 14, _, implicit %r0
@@ -274,9 +289,15 @@ registers:
   - { id: 0, class: gprb }
   - { id: 1, class: gprb }
   - { id: 2, class: gprb }
+  - { id: 3, class: gprb }
+  - { id: 4, class: gprb }
+  - { id: 5, class: gprb }
 # CHECK-DAG: id: 0, class: gpr
 # CHECK-DAG: id: 1, class: gpr
 # CHECK-DAG: id: 2, class: gpr
+# CHECK-DAG: id: 3, class: gpr
+# CHECK-DAG: id: 4, class: gpr
+# CHECK-DAG: id: 5, class: gpr
 body:             |
   bb.0:
     liveins: %r0, %r1
@@ -287,11 +308,20 @@ body:             |
     %1(s16) = COPY %r1
     ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1
 
-    %2(s16) = G_ADD %0, %1
-    ; CHECK: [[VREGSUM:%[0-9]+]] = ADDrr [[VREGX]], [[VREGY]], 14, _, _
+    %2(s32) = G_ANYEXT %0(s16)
+    ; CHECK: [[VREGXEXT:%[0-9]+]] = COPY [[VREGX]]
 
-    %r0 = COPY %2(s16)
-    ; CHECK: %r0 = COPY [[VREGSUM]]
+    %3(s32) = G_ANYEXT %1(s16)
+    ; CHECK: [[VREGYEXT:%[0-9]+]] = COPY [[VREGY]]
+
+    %4(s32) = G_ADD %2, %3
+    ; CHECK: [[VREGSUM:%[0-9]+]] = ADDrr [[VREGXEXT]], [[VREGYEXT]], 14, _, _
+
+    %5(s16) = G_TRUNC %4(s32)
+    ; CHECK: [[VREGSUMTR:%[0-9]+]] = COPY [[VREGSUM]]
+
+    %r0 = COPY %5(s16)
+    ; CHECK: %r0 = COPY [[VREGSUMTR]]
 
     BX_RET 14, _, implicit %r0
     ; CHECK: BX_RET 14, _, implicit %r0
@@ -406,9 +436,15 @@ registers:
   - { id: 0, class: gprb }
   - { id: 1, class: gprb }
   - { id: 2, class: gprb }
+  - { id: 3, class: gprb }
+  - { id: 4, class: gprb }
+  - { id: 5, class: gprb }
 # CHECK-DAG: id: 0, class: gpr
 # CHECK-DAG: id: 1, class: gpr
 # CHECK-DAG: id: 2, class: gpr
+# CHECK-DAG: id: 3, class: gpr
+# CHECK-DAG: id: 4, class: gpr
+# CHECK-DAG: id: 5, class: gpr
 body:             |
   bb.0:
     liveins: %r0, %r1
@@ -419,11 +455,20 @@ body:             |
     %1(s8) = COPY %r1
     ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1
 
-    %2(s8) = G_SUB %0, %1
-    ; CHECK: [[VREGRES:%[0-9]+]] = SUBrr [[VREGX]], [[VREGY]], 14, _, _
+    %2(s32) = G_ANYEXT %0(s8)
+    ; CHECK: [[VREGXEXT:%[0-9]+]] = COPY [[VREGX]]
 
-    %r0 = COPY %2(s8)
-    ; CHECK: %r0 = COPY [[VREGRES]]
+    %3(s32) = G_ANYEXT %1(s8)
+    ; CHECK: [[VREGYEXT:%[0-9]+]] = COPY [[VREGY]]
+
+    %4(s32) = G_SUB %2, %3
+    ; CHECK: [[VREGRES:%[0-9]+]] = SUBrr [[VREGXEXT]], [[VREGYEXT]], 14, _, _
+
+    %5(s8) = G_TRUNC %4(s32)
+    ; CHECK: [[VREGRESTR:%[0-9]+]] = COPY [[VREGRES]]
+
+    %r0 = COPY %5(s8)
+    ; CHECK: %r0 = COPY [[VREGRESTR]]
 
     BX_RET 14, _, implicit %r0
     ; CHECK: BX_RET 14, _, implicit %r0
@@ -439,9 +484,15 @@ registers:
   - { id: 0, class: gprb }
   - { id: 1, class: gprb }
   - { id: 2, class: gprb }
+  - { id: 3, class: gprb }
+  - { id: 4, class: gprb }
+  - { id: 5, class: gprb }
 # CHECK-DAG: id: 0, class: gpr
 # CHECK-DAG: id: 1, class: gpr
 # CHECK-DAG: id: 2, class: gpr
+# CHECK-DAG: id: 3, class: gpr
+# CHECK-DAG: id: 4, class: gpr
+# CHECK-DAG: id: 5, class: gpr
 body:             |
   bb.0:
     liveins: %r0, %r1
@@ -452,11 +503,20 @@ body:             |
     %1(s16) = COPY %r1
     ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1
 
-    %2(s16) = G_SUB %0, %1
-    ; CHECK: [[VREGRES:%[0-9]+]] = SUBrr [[VREGX]], [[VREGY]], 14, _, _
+    %2(s32) = G_ANYEXT %0(s16)
+    ; CHECK: [[VREGXEXT:%[0-9]+]] = COPY [[VREGX]]
 
-    %r0 = COPY %2(s16)
-    ; CHECK: %r0 = COPY [[VREGRES]]
+    %3(s32) = G_ANYEXT %1(s16)
+    ; CHECK: [[VREGYEXT:%[0-9]+]] = COPY [[VREGY]]
+
+    %4(s32) = G_SUB %2, %3
+    ; CHECK: [[VREGRES:%[0-9]+]] = SUBrr [[VREGXEXT]], [[VREGYEXT]], 14, _, _
+
+    %5(s16) = G_TRUNC %4(s32)
+    ; CHECK: [[VREGRESTR:%[0-9]+]] = COPY [[VREGRES]]
+
+    %r0 = COPY %5(s16)
+    ; CHECK: %r0 = COPY [[VREGRESTR]]
 
     BX_RET 14, _, implicit %r0
     ; CHECK: BX_RET 14, _, implicit %r0
@@ -505,9 +565,15 @@ registers:
   - { id: 0, class: gprb }
   - { id: 1, class: gprb }
   - { id: 2, class: gprb }
-# CHECK-DAG: id: 0, class: gprnopc
-# CHECK-DAG: id: 1, class: gprnopc
+  - { id: 3, class: gprb }
+  - { id: 4, class: gprb }
+  - { id: 5, class: gprb }
+# CHECK-DAG: id: 0, class: gpr
+# CHECK-DAG: id: 1, class: gpr
 # CHECK-DAG: id: 2, class: gprnopc
+# CHECK-DAG: id: 3, class: gprnopc
+# CHECK-DAG: id: 4, class: gprnopc
+# CHECK-DAG: id: 5, class: gpr
 body:             |
   bb.0:
     liveins: %r0, %r1
@@ -518,11 +584,20 @@ body:             |
     %1(s8) = COPY %r1
     ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1
 
-    %2(s8) = G_MUL %0, %1
-    ; CHECK: [[VREGRES:%[0-9]+]] = MUL [[VREGX]], [[VREGY]], 14, _, _
+    %2(s32) = G_ANYEXT %0(s8)
+    ; CHECK: [[VREGXEXT:%[0-9]+]] = COPY [[VREGX]]
 
-    %r0 = COPY %2(s8)
-    ; CHECK: %r0 = COPY [[VREGRES]]
+    %3(s32) = G_ANYEXT %1(s8)
+    ; CHECK: [[VREGYEXT:%[0-9]+]] = COPY [[VREGY]]
+
+    %4(s32) = G_MUL %2, %3
+    ; CHECK: [[VREGRES:%[0-9]+]] = MUL [[VREGXEXT]], [[VREGYEXT]], 14, _, _
+
+    %5(s8) = G_TRUNC %4(s32)
+    ; CHECK: [[VREGRESTR:%[0-9]+]] = COPY [[VREGRES]]
+
+    %r0 = COPY %5(s8)
+    ; CHECK: %r0 = COPY [[VREGRESTR]]
 
     BX_RET 14, _, implicit %r0
     ; CHECK: BX_RET 14, _, implicit %r0
@@ -538,9 +613,15 @@ registers:
   - { id: 0, class: gprb }
   - { id: 1, class: gprb }
   - { id: 2, class: gprb }
-# CHECK-DAG: id: 0, class: gprnopc
-# CHECK-DAG: id: 1, class: gprnopc
+  - { id: 3, class: gprb }
+  - { id: 4, class: gprb }
+  - { id: 5, class: gprb }
+# CHECK-DAG: id: 0, class: gpr
+# CHECK-DAG: id: 1, class: gpr
 # CHECK-DAG: id: 2, class: gprnopc
+# CHECK-DAG: id: 3, class: gprnopc
+# CHECK-DAG: id: 4, class: gprnopc
+# CHECK-DAG: id: 5, class: gpr
 body:             |
   bb.0:
     liveins: %r0, %r1
@@ -551,11 +632,20 @@ body:             |
     %1(s16) = COPY %r1
     ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1
 
-    %2(s16) = G_MUL %0, %1
-    ; CHECK: [[VREGRES:%[0-9]+]] = MUL [[VREGX]], [[VREGY]], 14, _, _
+    %2(s32) = G_ANYEXT %0(s16)
+    ; CHECK: [[VREGXEXT:%[0-9]+]] = COPY [[VREGX]]
 
-    %r0 = COPY %2(s16)
-    ; CHECK: %r0 = COPY [[VREGRES]]
+    %3(s32) = G_ANYEXT %1(s16)
+    ; CHECK: [[VREGYEXT:%[0-9]+]] = COPY [[VREGY]]
+
+    %4(s32) = G_MUL %2, %3
+    ; CHECK: [[VREGRES:%[0-9]+]] = MUL [[VREGXEXT]], [[VREGYEXT]], 14, _, _
+
+    %5(s16) = G_TRUNC %4(s32)
+    ; CHECK: [[VREGRESTR:%[0-9]+]] = COPY [[VREGRES]]
+
+    %r0 = COPY %5(s16)
+    ; CHECK: %r0 = COPY [[VREGRESTR]]
 
     BX_RET 14, _, implicit %r0
     ; CHECK: BX_RET 14, _, implicit %r0
index 625d35acf17b955fdd4d86d81657b9e955e4834d..f6ac92597cb291b3ec90cf73a9582469e4032bbb 100644 (file)
@@ -91,8 +91,9 @@ body:             |
     %0(s8) = COPY %r0
     %1(s8) = COPY %r1
     %2(s8) = G_ADD %0, %1
-    ; G_ADD with s8 is legal, so we should find it unchanged in the output
-    ; CHECK: {{%[0-9]+}}(s8) = G_ADD {{%[0-9]+, %[0-9]+}}
+    ; G_ADD with s8 should widen
+    ; CHECK: {{%[0-9]+}}(s32) = G_ADD {{%[0-9]+, %[0-9]+}}
+    ; CHECK-NOT: {{%[0-9]+}}(s8) = G_ADD {{%[0-9]+, %[0-9]+}}
     %r0 = COPY %2(s8)
     BX_RET 14, _, implicit %r0
 ...
@@ -115,8 +116,9 @@ body:             |
     %0(s16) = COPY %r0
     %1(s16) = COPY %r1
     %2(s16) = G_ADD %0, %1
-    ; G_ADD with s16 is legal, so we should find it unchanged in the output
-    ; CHECK: {{%[0-9]+}}(s16) = G_ADD {{%[0-9]+, %[0-9]+}}
+    ; G_ADD with s16 should widen
+    ; CHECK: {{%[0-9]+}}(s32) = G_ADD {{%[0-9]+, %[0-9]+}}
+    ; CHECK-NOT: {{%[0-9]+}}(s16) = G_ADD {{%[0-9]+, %[0-9]+}}
     %r0 = COPY %2(s16)
     BX_RET 14, _, implicit %r0
 
@@ -165,8 +167,9 @@ body:             |
     %0(s8) = COPY %r0
     %1(s8) = COPY %r1
     %2(s8) = G_SUB %0, %1
-    ; G_SUB with s8 is legal, so we should find it unchanged in the output
-    ; CHECK: {{%[0-9]+}}(s8) = G_SUB {{%[0-9]+, %[0-9]+}}
+    ; G_SUB with s8 should widen
+    ; CHECK: {{%[0-9]+}}(s32) = G_SUB {{%[0-9]+, %[0-9]+}}
+    ; CHECK-NOT: {{%[0-9]+}}(s8) = G_SUB {{%[0-9]+, %[0-9]+}}
     %r0 = COPY %2(s8)
     BX_RET 14, _, implicit %r0
 ...
@@ -189,8 +192,9 @@ body:             |
     %0(s16) = COPY %r0
     %1(s16) = COPY %r1
     %2(s16) = G_SUB %0, %1
-    ; G_SUB with s16 is legal, so we should find it unchanged in the output
-    ; CHECK: {{%[0-9]+}}(s16) = G_SUB {{%[0-9]+, %[0-9]+}}
+    ; G_SUB with s16 should widen
+    ; CHECK: {{%[0-9]+}}(s32) = G_SUB {{%[0-9]+, %[0-9]+}}
+    ; CHECK-NOT: {{%[0-9]+}}(s16) = G_SUB {{%[0-9]+, %[0-9]+}}
     %r0 = COPY %2(s16)
     BX_RET 14, _, implicit %r0
 
@@ -239,8 +243,9 @@ body:             |
     %0(s8) = COPY %r0
     %1(s8) = COPY %r1
     %2(s8) = G_MUL %0, %1
-    ; G_MUL with s8 is legal, so we should find it unchanged in the output
-    ; CHECK: {{%[0-9]+}}(s8) = G_MUL {{%[0-9]+, %[0-9]+}}
+    ; G_MUL with s8 should widen
+    ; CHECK: {{%[0-9]+}}(s32) = G_MUL {{%[0-9]+, %[0-9]+}}
+    ; CHECK-NOT: {{%[0-9]+}}(s8) = G_MUL {{%[0-9]+, %[0-9]+}}
     %r0 = COPY %2(s8)
     BX_RET 14, _, implicit %r0
 ...
@@ -263,8 +268,9 @@ body:             |
     %0(s16) = COPY %r0
     %1(s16) = COPY %r1
     %2(s16) = G_MUL %0, %1
-    ; G_MUL with s16 is legal, so we should find it unchanged in the output
-    ; CHECK: {{%[0-9]+}}(s16) = G_MUL {{%[0-9]+, %[0-9]+}}
+    ; G_MUL with s16 should widen
+    ; CHECK: {{%[0-9]+}}(s32) = G_MUL {{%[0-9]+, %[0-9]+}}
+    ; CHECK-NOT: {{%[0-9]+}}(s16) = G_MUL {{%[0-9]+, %[0-9]+}}
     %r0 = COPY %2(s16)
     BX_RET 14, _, implicit %r0
 
index b887487cc3f6f2d294210ca7d30a6343d046a609..dfccc47c277c9f9be1089b05049d478136820a5b 100644 (file)
@@ -74,19 +74,28 @@ selected:        false
 # CHECK: - { id: 0, class: gprb }
 # CHECK: - { id: 1, class: gprb }
 # CHECK: - { id: 2, class: gprb }
+# CHECK: - { id: 3, class: gprb }
+# CHECK: - { id: 4, class: gprb }
+# CHECK: - { id: 5, class: gprb }
 
 registers:
   - { id: 0, class: _ }
   - { id: 1, class: _ }
   - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+  - { id: 5, class: _ }
 body:             |
   bb.0:
     liveins: %r0, %r1
 
     %0(s16) = COPY %r0
     %1(s16) = COPY %r1
-    %2(s16) = G_ADD %0, %1
-    %r0 = COPY %2(s16)
+    %2(s32) = G_ANYEXT %0(s16)
+    %3(s32) = G_ANYEXT %1(s16)
+    %4(s32) = G_ADD %2, %3
+    %5(s16) = G_TRUNC %4(s32)
+    %r0 = COPY %5(s16)
     BX_RET 14, _, implicit %r0
 
 ...
@@ -100,19 +109,28 @@ selected:        false
 # CHECK: - { id: 0, class: gprb }
 # CHECK: - { id: 1, class: gprb }
 # CHECK: - { id: 2, class: gprb }
+# CHECK: - { id: 3, class: gprb }
+# CHECK: - { id: 4, class: gprb }
+# CHECK: - { id: 5, class: gprb }
 
 registers:
   - { id: 0, class: _ }
   - { id: 1, class: _ }
   - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+  - { id: 5, class: _ }
 body:             |
   bb.0:
     liveins: %r0, %r1
 
     %0(s8) = COPY %r0
     %1(s8) = COPY %r1
-    %2(s8) = G_ADD %0, %1
-    %r0 = COPY %2(s8)
+    %2(s32) = G_ANYEXT %0(s8)
+    %3(s32) = G_ANYEXT %1(s8)
+    %4(s32) = G_ADD %2, %3
+    %5(s8) = G_TRUNC %4(s32)
+    %r0 = COPY %5(s8)
     BX_RET 14, _, implicit %r0
 
 ...
@@ -126,19 +144,28 @@ selected:        false
 # CHECK: - { id: 0, class: gprb }
 # CHECK: - { id: 1, class: gprb }
 # CHECK: - { id: 2, class: gprb }
+# CHECK: - { id: 3, class: gprb }
+# CHECK: - { id: 4, class: gprb }
+# CHECK: - { id: 5, class: gprb }
 
 registers:
   - { id: 0, class: _ }
   - { id: 1, class: _ }
   - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+  - { id: 5, class: _ }
 body:             |
   bb.0:
     liveins: %r0, %r1
 
     %0(s1) = COPY %r0
     %1(s1) = COPY %r1
-    %2(s1) = G_ADD %0, %1
-    %r0 = COPY %2(s1)
+    %2(s32) = G_ANYEXT %0(s1)
+    %3(s32) = G_ANYEXT %1(s1)
+    %4(s32) = G_ADD %2, %3
+    %5(s1) = G_TRUNC %4(s32)
+    %r0 = COPY %5(s1)
     BX_RET 14, _, implicit %r0
 
 ...
@@ -178,19 +205,28 @@ selected:        false
 # CHECK: - { id: 0, class: gprb }
 # CHECK: - { id: 1, class: gprb }
 # CHECK: - { id: 2, class: gprb }
+# CHECK: - { id: 3, class: gprb }
+# CHECK: - { id: 4, class: gprb }
+# CHECK: - { id: 5, class: gprb }
 
 registers:
   - { id: 0, class: _ }
   - { id: 1, class: _ }
   - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+  - { id: 5, class: _ }
 body:             |
   bb.0:
     liveins: %r0, %r1
 
     %0(s16) = COPY %r0
     %1(s16) = COPY %r1
-    %2(s16) = G_SUB %0, %1
-    %r0 = COPY %2(s16)
+    %2(s32) = G_ANYEXT %0(s16)
+    %3(s32) = G_ANYEXT %1(s16)
+    %4(s32) = G_SUB %2, %3
+    %5(s16) = G_TRUNC %4(s32)
+    %r0 = COPY %5(s16)
     BX_RET 14, _, implicit %r0
 
 ...
@@ -204,19 +240,28 @@ selected:        false
 # CHECK: - { id: 0, class: gprb }
 # CHECK: - { id: 1, class: gprb }
 # CHECK: - { id: 2, class: gprb }
+# CHECK: - { id: 3, class: gprb }
+# CHECK: - { id: 4, class: gprb }
+# CHECK: - { id: 5, class: gprb }
 
 registers:
   - { id: 0, class: _ }
   - { id: 1, class: _ }
   - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+  - { id: 5, class: _ }
 body:             |
   bb.0:
     liveins: %r0, %r1
 
     %0(s8) = COPY %r0
     %1(s8) = COPY %r1
-    %2(s8) = G_SUB %0, %1
-    %r0 = COPY %2(s8)
+    %2(s32) = G_ANYEXT %0(s8)
+    %3(s32) = G_ANYEXT %1(s8)
+    %4(s32) = G_SUB %2, %3
+    %5(s8) = G_TRUNC %4(s32)
+    %r0 = COPY %5(s8)
     BX_RET 14, _, implicit %r0
 
 ...
@@ -256,19 +301,28 @@ selected:        false
 # CHECK: - { id: 0, class: gprb }
 # CHECK: - { id: 1, class: gprb }
 # CHECK: - { id: 2, class: gprb }
+# CHECK: - { id: 3, class: gprb }
+# CHECK: - { id: 4, class: gprb }
+# CHECK: - { id: 5, class: gprb }
 
 registers:
   - { id: 0, class: _ }
   - { id: 1, class: _ }
   - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+  - { id: 5, class: _ }
 body:             |
   bb.0:
     liveins: %r0, %r1
 
     %0(s16) = COPY %r0
     %1(s16) = COPY %r1
-    %2(s16) = G_MUL %0, %1
-    %r0 = COPY %2(s16)
+    %2(s32) = G_ANYEXT %0(s16)
+    %3(s32) = G_ANYEXT %1(s16)
+    %4(s32) = G_MUL %2, %3
+    %5(s16) = G_TRUNC %4(s32)
+    %r0 = COPY %5(s16)
     BX_RET 14, _, implicit %r0
 
 ...
@@ -282,19 +336,28 @@ selected:        false
 # CHECK: - { id: 0, class: gprb }
 # CHECK: - { id: 1, class: gprb }
 # CHECK: - { id: 2, class: gprb }
+# CHECK: - { id: 3, class: gprb }
+# CHECK: - { id: 4, class: gprb }
+# CHECK: - { id: 5, class: gprb }
 
 registers:
   - { id: 0, class: _ }
   - { id: 1, class: _ }
   - { id: 2, class: _ }
+  - { id: 3, class: _ }
+  - { id: 4, class: _ }
+  - { id: 5, class: _ }
 body:             |
   bb.0:
     liveins: %r0, %r1
 
     %0(s8) = COPY %r0
     %1(s8) = COPY %r1
-    %2(s8) = G_MUL %0, %1
-    %r0 = COPY %2(s8)
+    %2(s32) = G_ANYEXT %0(s8)
+    %3(s32) = G_ANYEXT %1(s8)
+    %4(s32) = G_MUL %2, %3
+    %5(s8) = G_TRUNC %4(s32)
+    %r0 = COPY %5(s8)
     BX_RET 14, _, implicit %r0
 
 ...