[torque][csa] fix word8 phi MachineRepresentation

Make sure that Torque/CSA generated phi's get kRepWord32 instead
of kRepWord8 or kRepWord16, since that's how we handle small
integer values in Turbofan.

Bug: v8:7793
Change-Id: I992b43287552b6117e90fbd0e11576470bc91509
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2339096
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69253}
diff --git a/src/builtins/base.tq b/src/builtins/base.tq
index fd76137..760783c 100644
--- a/src/builtins/base.tq
+++ b/src/builtins/base.tq
@@ -835,6 +835,7 @@
 extern operator '!=' macro Word32NotEqual(int32, int32): bool;
 extern operator '!=' macro Word32NotEqual(uint32, uint32): bool;
 extern operator '>>>' macro Word32Shr(uint32, uint32): uint32;
+extern operator '>>' macro Word32Sar(int32, int32): int32;
 extern operator '<<' macro Word32Shl(int32, int32): int32;
 extern operator '<<' macro Word32Shl(uint32, uint32): uint32;
 extern operator '|' macro Word32Or(int32, int32): int32;
diff --git a/src/builtins/convert.tq b/src/builtins/convert.tq
index dfb6d52..670d475 100644
--- a/src/builtins/convert.tq
+++ b/src/builtins/convert.tq
@@ -52,6 +52,11 @@
   static_assert(i <= 255);
   return %RawDownCast<uint8>(i);
 }
+FromConstexpr<int8, constexpr int31>(i: constexpr int31): int8 {
+  const i: int32 = i;
+  static_assert(-128 <= i && i <= 127);
+  return %RawDownCast<int8>(i);
+}
 FromConstexpr<Number, constexpr Smi>(s: constexpr Smi): Number {
   return SmiConstant(s);
 }
@@ -149,6 +154,9 @@
 Convert<uint8, intptr>(i: intptr): uint8 {
   return %RawDownCast<uint8>(Unsigned(TruncateIntPtrToInt32(i)) & 0xFF);
 }
+Convert<int8, intptr>(i: intptr): int8 {
+  return %RawDownCast<int8>(TruncateIntPtrToInt32(i) << 24 >> 24);
+}
 Convert<int32, uint8>(i: uint8): int32 {
   return Signed(Convert<uint32>(i));
 }
diff --git a/src/codegen/tnode.h b/src/codegen/tnode.h
index 1b1df5d..7cfbb62 100644
--- a/src/codegen/tnode.h
+++ b/src/codegen/tnode.h
@@ -191,6 +191,11 @@
 }
 
 template <class T>
+constexpr MachineRepresentation PhiMachineRepresentationOf =
+    std::is_base_of<Word32T, T>::value ? MachineRepresentation::kWord32
+                                       : MachineRepresentationOf<T>::value;
+
+template <class T>
 struct is_valid_type_tag {
   static const bool value = std::is_base_of<Object, T>::value ||
                             std::is_base_of<UntaggedT, T>::value ||
diff --git a/src/compiler/code-assembler.h b/src/compiler/code-assembler.h
index 9f6506b..203e1ee 100644
--- a/src/compiler/code-assembler.h
+++ b/src/compiler/code-assembler.h
@@ -819,6 +819,10 @@
     return Unsigned(
         Word32Shr(static_cast<Node*>(left), static_cast<Node*>(right)));
   }
+  TNode<Int32T> Word32Sar(TNode<Int32T> left, TNode<Int32T> right) {
+    return Signed(
+        Word32Sar(static_cast<Node*>(left), static_cast<Node*>(right)));
+  }
 
   TNode<IntPtrT> WordAnd(TNode<IntPtrT> left, TNode<IntPtrT> right) {
     return Signed(WordAnd(static_cast<Node*>(left), static_cast<Node*>(right)));
@@ -1270,20 +1274,19 @@
 class TypedCodeAssemblerVariable : public CodeAssemblerVariable {
  public:
   TypedCodeAssemblerVariable(TNode<T> initial_value, CodeAssembler* assembler)
-      : CodeAssemblerVariable(assembler, MachineRepresentationOf<T>::value,
+      : CodeAssemblerVariable(assembler, PhiMachineRepresentationOf<T>,
                               initial_value) {}
   explicit TypedCodeAssemblerVariable(CodeAssembler* assembler)
-      : CodeAssemblerVariable(assembler, MachineRepresentationOf<T>::value) {}
+      : CodeAssemblerVariable(assembler, PhiMachineRepresentationOf<T>) {}
 #if DEBUG
   TypedCodeAssemblerVariable(AssemblerDebugInfo debug_info,
                              CodeAssembler* assembler)
       : CodeAssemblerVariable(assembler, debug_info,
-                              MachineRepresentationOf<T>::value) {}
+                              PhiMachineRepresentationOf<T>) {}
   TypedCodeAssemblerVariable(AssemblerDebugInfo debug_info,
                              TNode<T> initial_value, CodeAssembler* assembler)
       : CodeAssemblerVariable(assembler, debug_info,
-                              MachineRepresentationOf<T>::value,
-                              initial_value) {}
+                              PhiMachineRepresentationOf<T>, initial_value) {}
 #endif  // DEBUG
 
   TNode<T> value() const {
@@ -1407,7 +1410,7 @@
   void CreatePhis(TNode<Types>*... results) {
     const std::vector<Node*>& phi_nodes =
         CodeAssemblerParameterizedLabelBase::CreatePhis(
-            {MachineRepresentationOf<Types>::value...});
+            {PhiMachineRepresentationOf<Types>...});
     auto it = phi_nodes.begin();
     USE(it);
     ITERATE_PACK(AssignPhi(results, *(it++)));
diff --git a/test/cctest/torque/test-torque.cc b/test/cctest/torque/test-torque.cc
index c206c9d..af45e58 100644
--- a/test/cctest/torque/test-torque.cc
+++ b/test/cctest/torque/test-torque.cc
@@ -852,6 +852,20 @@
   ft.Call();
 }
 
+TEST(TestWord8Phi) {
+  CcTest::InitializeVM();
+  Isolate* isolate(CcTest::i_isolate());
+  i::HandleScope scope(isolate);
+  CodeAssemblerTester asm_tester(isolate, 1);
+  TestTorqueAssembler m(asm_tester.state());
+  {
+    m.TestWord8Phi();
+    m.Return(m.UndefinedConstant());
+  }
+  FunctionTester ft(asm_tester.GenerateCode(), 0);
+  ft.Call();
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/test/torque/test-torque.tq b/test/torque/test-torque.tq
index fcf0aaa..8eabf82 100644
--- a/test/torque/test-torque.tq
+++ b/test/torque/test-torque.tq
@@ -1327,4 +1327,17 @@
   assert(Is<ExportedSubClassBase>(obj));
   assert(InYoungGeneration(obj) == False);
 }
+
+@export
+macro TestWord8Phi() {
+  for (let i: intptr = -5; i < 5; ++i) {
+    let x: int8;
+    if (i == -1) {
+      x = -1;
+    } else {
+      x = Convert<int8>(i);
+    }
+    check(x == Convert<int8>(i));
+  }
+}
 }