Skip to content

Commit eb38a18

Browse files
nikicalexcrichton
authored andcommitted
[WebAssembly] Don't assume that zext/sext result is i32/i64 in fast isel (PR41841)
Usually this will abort fast-isel at the instruction using the non-legal result, but if the only use is in a different basic block, we'll incorrectly assume that the zext/sext is to i32 (rather than i128 in this case). Differential Revision: https://reviews.llvm.org/D61823 llvm-svn: 360616
1 parent 84abffd commit eb38a18

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,10 @@ unsigned WebAssemblyFastISel::zeroExtend(unsigned Reg, const Value *V,
524524
return Result;
525525
}
526526

527-
return zeroExtendToI32(Reg, V, From);
527+
if (To == MVT::i32)
528+
return zeroExtendToI32(Reg, V, From);
529+
530+
return 0;
528531
}
529532

530533
unsigned WebAssemblyFastISel::signExtend(unsigned Reg, const Value *V,
@@ -543,7 +546,10 @@ unsigned WebAssemblyFastISel::signExtend(unsigned Reg, const Value *V,
543546
return Result;
544547
}
545548

546-
return signExtendToI32(Reg, V, From);
549+
if (To == MVT::i32)
550+
return signExtendToI32(Reg, V, From);
551+
552+
return 0;
547553
}
548554

549555
unsigned WebAssemblyFastISel::getRegForUnsignedValue(const Value *V) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
; RUN: llc < %s -O0 -wasm-disable-explicit-locals -wasm-keep-registers -asm-verbose=false | FileCheck %s
2+
3+
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
4+
target triple = "wasm32-unknown-unknown"
5+
6+
declare void @foo(i128)
7+
8+
; CHECK-LABEL: test_zext:
9+
; CHECK-NEXT: .functype test_zext (i32) -> (){{$}}
10+
; CHECK-NEXT: i64.extend_i32_u $[[TMP3:[0-9]+]]=, $0{{$}}
11+
; CHECK-NEXT: i64.const $[[TMP4:[0-9]+]]=, 1{{$}}
12+
; CHECK-NEXT: i64.and $[[TMP1:[0-9]+]]=, $[[TMP3]], $[[TMP4]]{{$}}
13+
; CHECK-NEXT: i64.const $[[TMP2:[0-9]+]]=, 0{{$}}
14+
; CHECK-NEXT: call foo, $[[TMP1]], $[[TMP2]]{{$}}
15+
; CHECK-NEXT: return{{$}}
16+
define void @test_zext(i1 %b) nounwind {
17+
%res = zext i1 %b to i128
18+
br label %next
19+
20+
next: ; preds = %start
21+
call void @foo(i128 %res)
22+
ret void
23+
}
24+
25+
; CHECK-LABEL: test_sext:
26+
; CHECK-NEXT:.functype test_sext (i32) -> (){{$}}
27+
; CHECK-NEXT: i64.extend_i32_u $[[TMP3:[0-9]+]]=, $0{{$}}
28+
; CHECK-NEXT: i64.const $[[TMP4:[0-9]+]]=, 1{{$}}
29+
; CHECK-NEXT: i64.and $[[TMP5:[0-9]+]]=, $[[TMP3]], $[[TMP4]]{{$}}
30+
; CHECK-NEXT: i64.const $[[TMP6:[0-9]+]]=, 0{{$}}
31+
; CHECK-NEXT: i64.sub $[[TMP1:[0-9]+]]=, $[[TMP6]], $[[TMP5]]{{$}}
32+
; CHECK-NEXT: local.copy $[[TMP2:[0-9]+]]=, $[[TMP1]]{{$}}
33+
; CHECK-NEXT: call foo, $[[TMP1]], $[[TMP2]]{{$}}
34+
; CHECK-NEXT: return{{$}}
35+
define void @test_sext(i1 %b) nounwind {
36+
%res = sext i1 %b to i128
37+
br label %next
38+
39+
next: ; preds = %start
40+
call void @foo(i128 %res)
41+
ret void
42+
}

0 commit comments

Comments
 (0)