[llvm] 9d89b05 - [WebAssembly] Fix trunc in FastISel (#138479)

via llvm-commits llvm-commits at lists.llvm.org
Tue May 6 14:16:39 PDT 2025


Author: Pavel Verigo
Date: 2025-05-06T14:16:35-07:00
New Revision: 9d89b05f1147dc442794186f505e30a27ffe75a7

URL: https://github.com/llvm/llvm-project/commit/9d89b05f1147dc442794186f505e30a27ffe75a7
DIFF: https://github.com/llvm/llvm-project/commit/9d89b05f1147dc442794186f505e30a27ffe75a7.diff

LOG: [WebAssembly] Fix trunc in FastISel (#138479)

Previous logic did not handle the case where the result bit size was
between 32 and 64 bits inclusive. I updated the if-statements for more
precise handling.

An alternative solution would have been to abort FastISel in case the
result type is not legal for FastISel.

Resolves: #64222.

This PR began as an investigation into the root cause of
https://github.com/ziglang/zig/issues/20966.

Godbolt link showing incorrect codegen on 20.1.0:
https://godbolt.org/z/cEr4vY7d4.

Added: 
    llvm/test/CodeGen/WebAssembly/fast-isel-pr138479.ll

Modified: 
    llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
index 78c6a41624291..b2ea784057780 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -992,7 +992,10 @@ bool WebAssemblyFastISel::selectTrunc(const Instruction *I) {
   if (Reg == 0)
     return false;
 
-  if (Trunc->getOperand(0)->getType()->isIntegerTy(64)) {
+  unsigned FromBitWidth = Trunc->getOperand(0)->getType()->getIntegerBitWidth();
+  unsigned ToBitWidth = Trunc->getType()->getIntegerBitWidth();
+
+  if (ToBitWidth <= 32 && (32 < FromBitWidth && FromBitWidth <= 64)) {
     Register Result = createResultReg(&WebAssembly::I32RegClass);
     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
             TII.get(WebAssembly::I32_WRAP_I64), Result)

diff  --git a/llvm/test/CodeGen/WebAssembly/fast-isel-pr138479.ll b/llvm/test/CodeGen/WebAssembly/fast-isel-pr138479.ll
new file mode 100644
index 0000000000000..2676000b968c3
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/fast-isel-pr138479.ll
@@ -0,0 +1,15 @@
+; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 -verify-machineinstrs | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+declare void @extern48(i48)
+
+; CHECK-LABEL: call_trunc_i64_to_i48:
+; CHECK:       local.get 0
+; CHECK-NEXT:  call extern48
+; CHECK-NEXT:  end_function
+define void @call_trunc_i64_to_i48(i64 %x) {
+  %x48 = trunc i64 %x to i48
+  call void @extern48(i48 %x48)
+  ret void
+}


        


More information about the llvm-commits mailing list