Skip to content

Commit 9d89b05

Browse files
authored
[WebAssembly] Fix trunc in FastISel (llvm#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: llvm#64222. This PR began as an investigation into the root cause of ziglang/zig#20966. Godbolt link showing incorrect codegen on 20.1.0: https://godbolt.org/z/cEr4vY7d4.
1 parent 5c3ef62 commit 9d89b05

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -992,7 +992,10 @@ bool WebAssemblyFastISel::selectTrunc(const Instruction *I) {
992992
if (Reg == 0)
993993
return false;
994994

995-
if (Trunc->getOperand(0)->getType()->isIntegerTy(64)) {
995+
unsigned FromBitWidth = Trunc->getOperand(0)->getType()->getIntegerBitWidth();
996+
unsigned ToBitWidth = Trunc->getType()->getIntegerBitWidth();
997+
998+
if (ToBitWidth <= 32 && (32 < FromBitWidth && FromBitWidth <= 64)) {
996999
Register Result = createResultReg(&WebAssembly::I32RegClass);
9971000
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
9981001
TII.get(WebAssembly::I32_WRAP_I64), Result)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 -verify-machineinstrs | FileCheck %s
2+
3+
target triple = "wasm32-unknown-unknown"
4+
5+
declare void @extern48(i48)
6+
7+
; CHECK-LABEL: call_trunc_i64_to_i48:
8+
; CHECK: local.get 0
9+
; CHECK-NEXT: call extern48
10+
; CHECK-NEXT: end_function
11+
define void @call_trunc_i64_to_i48(i64 %x) {
12+
%x48 = trunc i64 %x to i48
13+
call void @extern48(i48 %x48)
14+
ret void
15+
}

0 commit comments

Comments
 (0)