about summary refs log tree commit diff
path: root/compiler/rustc_codegen_gcc/src/builder.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-05-17 02:50:33 +0000
committerbors <bors@rust-lang.org>2025-05-17 02:50:33 +0000
commita69bc17fb8026bdc0d24bb1896ff95f0eba1da4e (patch)
treebfc30fa4fe6f54b099d75803732deb0e08869c1a /compiler/rustc_codegen_gcc/src/builder.rs
parentc8bda740ea5c21af42fe4afa907f89805ab2b905 (diff)
parentd5c5a8251d0a9477ff6383638d5a8fdb2e109819 (diff)
downloadrust-a69bc17fb8026bdc0d24bb1896ff95f0eba1da4e.tar.gz
rust-a69bc17fb8026bdc0d24bb1896ff95f0eba1da4e.zip
Auto merge of #141002 - GuillaumeGomez:subtree-update_cg_gcc_2025-05-14, r=GuillaumeGomez
Subtree update GCC backend 2025 05 14

cc `@antoyo`
Diffstat (limited to 'compiler/rustc_codegen_gcc/src/builder.rs')
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs25
1 files changed, 21 insertions, 4 deletions
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index 9e5ebf3a9a4..4e2163201fd 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -568,11 +568,28 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
     ) {
         let mut gcc_cases = vec![];
         let typ = self.val_ty(value);
-        for (on_val, dest) in cases {
-            let on_val = self.const_uint_big(typ, on_val);
-            gcc_cases.push(self.context.new_case(on_val, on_val, dest));
+        // FIXME(FractalFir): This is a workaround for a libgccjit limitation.
+        // Currently, libgccjit can't directly create 128 bit integers.
+        // Since switch cases must be values, and casts are not constant, we can't use 128 bit switch cases.
+        // In such a case, we will simply fall back to an if-ladder.
+        // This *may* be slower than a native switch, but a slow working solution is better than none at all.
+        if typ.is_i128(self) || typ.is_u128(self) {
+            for (on_val, dest) in cases {
+                let on_val = self.const_uint_big(typ, on_val);
+                let is_case =
+                    self.context.new_comparison(self.location, ComparisonOp::Equals, value, on_val);
+                let next_block = self.current_func().new_block("case");
+                self.block.end_with_conditional(self.location, is_case, dest, next_block);
+                self.block = next_block;
+            }
+            self.block.end_with_jump(self.location, default_block);
+        } else {
+            for (on_val, dest) in cases {
+                let on_val = self.const_uint_big(typ, on_val);
+                gcc_cases.push(self.context.new_case(on_val, on_val, dest));
+            }
+            self.block.end_with_switch(self.location, value, default_block, &gcc_cases);
         }
-        self.block.end_with_switch(self.location, value, default_block, &gcc_cases);
     }
 
     #[cfg(feature = "master")]