Import Tint changes from Dawn

Changes:
  - 68e066a008e8097a8c7a77b27a1bef813ed69b5a [tint][utils] Minor tweaks to BumpAllocator by Ben Clayton <bclayton@google.com>
  - 6fddd7c1ba9465a59bafdd461e2c5429b0586c04 [tint][ir] Clone ControlInstruction results by James Price <jrprice@google.com>
GitOrigin-RevId: 68e066a008e8097a8c7a77b27a1bef813ed69b5a
Change-Id: Ib4d3a3c99d2c5aeb0d0fa231dd5315e71d502092
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/153920
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/core/ir/if.cc b/src/tint/lang/core/ir/if.cc
index e54d00f..15d1e5d 100644
--- a/src/tint/lang/core/ir/if.cc
+++ b/src/tint/lang/core/ir/if.cc
@@ -14,13 +14,13 @@
 
 #include "src/tint/lang/core/ir/if.h"
 
-TINT_INSTANTIATE_TYPEINFO(tint::core::ir::If);
-
 #include "src/tint/lang/core/ir/clone_context.h"
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/multi_in_block.h"
 #include "src/tint/utils/ice/ice.h"
 
+TINT_INSTANTIATE_TYPEINFO(tint::core::ir::If);
+
 namespace tint::core::ir {
 
 If::If(Value* cond, ir::Block* t, ir::Block* f) : true_(t), false_(f) {
@@ -58,6 +58,9 @@
 
     true_->CloneInto(ctx, new_true);
     false_->CloneInto(ctx, new_false);
+
+    new_if->SetResults(ctx.Clone(results_));
+
     return new_if;
 }
 
diff --git a/src/tint/lang/core/ir/if_test.cc b/src/tint/lang/core/ir/if_test.cc
index 01a8538..9ff0208 100644
--- a/src/tint/lang/core/ir/if_test.cc
+++ b/src/tint/lang/core/ir/if_test.cc
@@ -92,5 +92,27 @@
     EXPECT_EQ(new_if, new_if->True()->Front()->As<ExitIf>()->If());
 }
 
+TEST_F(IR_IfTest, CloneWithResults) {
+    If* new_if = nullptr;
+    auto* r0 = b.InstructionResult(ty.i32());
+    auto* r1 = b.InstructionResult(ty.f32());
+    {
+        auto* if_ = b.If(true);
+        if_->SetResults(Vector{r0, r1});
+        b.Append(if_->True(), [&] { b.ExitIf(if_, b.Constant(42_i), b.Constant(42_f)); });
+        new_if = clone_ctx.Clone(if_);
+    }
+
+    ASSERT_EQ(2u, new_if->Results().Length());
+    auto* new_r0 = new_if->Results()[0]->As<InstructionResult>();
+    ASSERT_NE(new_r0, nullptr);
+    ASSERT_NE(new_r0, r0);
+    EXPECT_EQ(new_r0->Type(), ty.i32());
+    auto* new_r1 = new_if->Results()[1]->As<InstructionResult>();
+    ASSERT_NE(new_r1, nullptr);
+    ASSERT_NE(new_r1, r1);
+    EXPECT_EQ(new_r1->Type(), ty.f32());
+}
+
 }  // namespace
 }  // namespace tint::core::ir
diff --git a/src/tint/lang/core/ir/loop.cc b/src/tint/lang/core/ir/loop.cc
index ada2516..11b42db 100644
--- a/src/tint/lang/core/ir/loop.cc
+++ b/src/tint/lang/core/ir/loop.cc
@@ -14,8 +14,6 @@
 
 #include "src/tint/lang/core/ir/loop.h"
 
-#include <utility>
-
 #include "src/tint/lang/core/ir/clone_context.h"
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/multi_in_block.h"
@@ -56,6 +54,8 @@
     body_->CloneInto(ctx, new_body);
     continuing_->CloneInto(ctx, new_continuing);
 
+    new_loop->SetResults(ctx.Clone(results_));
+
     return new_loop;
 }
 
diff --git a/src/tint/lang/core/ir/loop_test.cc b/src/tint/lang/core/ir/loop_test.cc
index 89699f0..53773f2 100644
--- a/src/tint/lang/core/ir/loop_test.cc
+++ b/src/tint/lang/core/ir/loop_test.cc
@@ -117,5 +117,27 @@
     EXPECT_EQ(new_loop, new_loop->Body()->Back()->As<NextIteration>()->Loop());
 }
 
+TEST_F(IR_LoopTest, CloneWithResults) {
+    Loop* new_loop = nullptr;
+    auto* r0 = b.InstructionResult(ty.i32());
+    auto* r1 = b.InstructionResult(ty.f32());
+    {
+        auto* loop = b.Loop();
+        loop->SetResults(Vector{r0, r1});
+        b.Append(loop->Body(), [&] { b.ExitLoop(loop, b.Constant(42_i), b.Constant(42_f)); });
+        new_loop = clone_ctx.Clone(loop);
+    }
+
+    ASSERT_EQ(2u, new_loop->Results().Length());
+    auto* new_r0 = new_loop->Results()[0]->As<InstructionResult>();
+    ASSERT_NE(new_r0, nullptr);
+    ASSERT_NE(new_r0, r0);
+    EXPECT_EQ(new_r0->Type(), ty.i32());
+    auto* new_r1 = new_loop->Results()[1]->As<InstructionResult>();
+    ASSERT_NE(new_r1, nullptr);
+    ASSERT_NE(new_r1, r1);
+    EXPECT_EQ(new_r1->Type(), ty.f32());
+}
+
 }  // namespace
 }  // namespace tint::core::ir
diff --git a/src/tint/lang/core/ir/switch.cc b/src/tint/lang/core/ir/switch.cc
index cae733b..395b668 100644
--- a/src/tint/lang/core/ir/switch.cc
+++ b/src/tint/lang/core/ir/switch.cc
@@ -54,6 +54,9 @@
         }
         new_switch->cases_.Push(new_case);
     }
+
+    new_switch->SetResults(ctx.Clone(results_));
+
     return new_switch;
 }
 
diff --git a/src/tint/lang/core/ir/switch_test.cc b/src/tint/lang/core/ir/switch_test.cc
index 83cc223..944ba97 100644
--- a/src/tint/lang/core/ir/switch_test.cc
+++ b/src/tint/lang/core/ir/switch_test.cc
@@ -101,5 +101,30 @@
     EXPECT_EQ(new_switch, case_.block->Front()->As<ExitSwitch>()->Switch());
 }
 
+TEST_F(IR_SwitchTest, CloneWithResults) {
+    Switch* new_switch = nullptr;
+    auto* r0 = b.InstructionResult(ty.i32());
+    auto* r1 = b.InstructionResult(ty.f32());
+    {
+        auto* switch_ = b.Switch(1_i);
+        switch_->SetResults(Vector{r0, r1});
+
+        auto* blk = b.Block();
+        b.Append(blk, [&] { b.ExitSwitch(switch_, b.Constant(42_i), b.Constant(42_f)); });
+        switch_->Cases().Push(Switch::Case{{Switch::CaseSelector{b.Constant(3_i)}}, blk});
+        new_switch = clone_ctx.Clone(switch_);
+    }
+
+    ASSERT_EQ(2u, new_switch->Results().Length());
+    auto* new_r0 = new_switch->Results()[0]->As<InstructionResult>();
+    ASSERT_NE(new_r0, nullptr);
+    ASSERT_NE(new_r0, r0);
+    EXPECT_EQ(new_r0->Type(), ty.i32());
+    auto* new_r1 = new_switch->Results()[1]->As<InstructionResult>();
+    ASSERT_NE(new_r1, nullptr);
+    ASSERT_NE(new_r1, r1);
+    EXPECT_EQ(new_r1->Type(), ty.f32());
+}
+
 }  // namespace
 }  // namespace tint::core::ir
diff --git a/src/tint/utils/memory/bump_allocator.h b/src/tint/utils/memory/bump_allocator.h
index c1df71a..6775d05 100644
--- a/src/tint/utils/memory/bump_allocator.h
+++ b/src/tint/utils/memory/bump_allocator.h
@@ -17,6 +17,7 @@
 
 #include <algorithm>
 #include <array>
+#include <cstddef>
 #include <cstring>
 #include <utility>
 
@@ -65,20 +66,21 @@
     /// current block is full.
     /// @param size_in_bytes the number of bytes to allocate
     /// @returns the pointer to the allocated memory or `nullptr` if the memory can not be allocated
-    uint8_t* Allocate(size_t size_in_bytes) {
+    std::byte* Allocate(size_t size_in_bytes) {
         if (TINT_UNLIKELY(data.current_offset + size_in_bytes < size_in_bytes)) {
             return nullptr;  // integer overflow
         }
         if (data.current_offset + size_in_bytes > data.current_data_size) {
             // Allocate a new block from the heap
             auto* prev_block = data.current;
-            data.current_data_size = std::max(size_in_bytes, kDefaultBlockDataSize);
-            data.current =
-                Bitcast<BlockHeader*>(new uint8_t[sizeof(BlockHeader) + data.current_data_size]);
-            if (!data.current) {
+            size_t data_size = std::max(size_in_bytes, kDefaultBlockDataSize);
+            data.current = Bitcast<BlockHeader*>(new (std::nothrow)
+                                                     std::byte[sizeof(BlockHeader) + data_size]);
+            if (TINT_UNLIKELY(!data.current)) {
                 return nullptr;  // out of memory
             }
             data.current->next = nullptr;
+            data.current_data_size = data_size;
             data.current_offset = 0;
             if (prev_block) {
                 prev_block->next = data.current;
@@ -87,7 +89,7 @@
             }
         }
 
-        auto* base = Bitcast<uint8_t*>(data.current) + sizeof(BlockHeader);
+        auto* base = Bitcast<std::byte*>(data.current) + sizeof(BlockHeader);
         auto* ptr = base + data.current_offset;
         data.current_offset += size_in_bytes;
         data.count++;
@@ -99,7 +101,7 @@
         auto* block = data.root;
         while (block != nullptr) {
             auto* next = block->next;
-            delete[] Bitcast<uint8_t*>(block);
+            delete[] Bitcast<std::byte*>(block);
             block = next;
         }
         data = {};
diff --git a/src/tint/utils/memory/bump_allocator_test.cc b/src/tint/utils/memory/bump_allocator_test.cc
index 31f3809..c1cc22a 100644
--- a/src/tint/utils/memory/bump_allocator_test.cc
+++ b/src/tint/utils/memory/bump_allocator_test.cc
@@ -34,12 +34,14 @@
     for (size_t n : {
              BumpAllocator::kDefaultBlockDataSize - sizeof(void*),
              BumpAllocator::kDefaultBlockDataSize - 4,
+             BumpAllocator::kDefaultBlockDataSize - 1,
              BumpAllocator::kDefaultBlockDataSize,
+             BumpAllocator::kDefaultBlockDataSize + 1,
              BumpAllocator::kDefaultBlockDataSize + 4,
              BumpAllocator::kDefaultBlockDataSize + sizeof(void*),
          }) {
         BumpAllocator allocator;
-        auto ptr = allocator.Allocate(n);
+        auto* ptr = allocator.Allocate(n);
         memset(ptr, 0x42, n);
     }
 }
diff --git a/src/tint/utils/symbol/symbol_table.cc b/src/tint/utils/symbol/symbol_table.cc
index 2830a41..c56c5c0 100644
--- a/src/tint/utils/symbol/symbol_table.cc
+++ b/src/tint/utils/symbol/symbol_table.cc
@@ -39,6 +39,7 @@
 Symbol SymbolTable::RegisterInternal(std::string_view name) {
     char* name_mem = Bitcast<char*>(name_allocator_.Allocate(name.length() + 1));
     if (name_mem == nullptr) {
+        TINT_ICE() << "failed to allocate memory for symbol's string";
         return Symbol();
     }