Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class WebAssemblyTargetLowering final : public TargetLowering {
MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const override;
MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const override;

bool softPromoteHalfType() const override { return true; }

private:
/// Keep a pointer to the WebAssemblySubtarget around so that we can make the
/// right decision when generating code for different targets.
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/Generic/half.ll
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
; RUN: %if spirv-registered-target %{ llc %s -o - -mtriple=spirv-unknown-unknown | FileCheck %s --check-prefixes=NOCRASH %}
; RUN: %if systemz-registered-target %{ llc %s -o - -mtriple=s390x-unknown-linux-gnu | FileCheck %s --check-prefixes=ALL,CHECK %}
; RUN: %if ve-registered-target %{ llc %s -o - -mtriple=ve-unknown-unknown | FileCheck %s --check-prefixes=ALL,BAD %}
; RUN: %if webassembly-registered-target %{ llc %s -o - -mtriple=wasm32-unknown-unknown | FileCheck %s --check-prefixes=ALL,BAD %}
; RUN: %if webassembly-registered-target %{ llc %s -o - -mtriple=wasm32-unknown-unknown | FileCheck %s --check-prefixes=ALL,CHECK %}
; RUN: %if x86-registered-target %{ llc %s -o - -mtriple=i686-unknown-linux-gnu | FileCheck %s --check-prefixes=ALL,CHECK %}
; RUN: %if x86-registered-target %{ llc %s -o - -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=ALL,CHECK %}
; RUN: %if x86-registered-target %{ llc %s -o - -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=ALL,CHECK %}
Expand Down
202 changes: 88 additions & 114 deletions llvm/test/CodeGen/WebAssembly/f16.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,23 @@ target triple = "wasm32-unknown-unknown"

define void @store(half %x, ptr %p) nounwind {
; ALL-LABEL: store:
; ALL: .functype store (f32, i32) -> ()
; ALL: .functype store (i32, i32) -> ()
; ALL-NEXT: # %bb.0:
; ALL-NEXT: local.get $push2=, 1
; ALL-NEXT: local.get $push1=, 0
; ALL-NEXT: call $push0=, __truncsfhf2, $pop1
; ALL-NEXT: i32.store16 0($pop2), $pop0
; ALL-NEXT: local.get $push1=, 1
; ALL-NEXT: local.get $push0=, 0
; ALL-NEXT: i32.store16 0($pop1), $pop0
; ALL-NEXT: return
store half %x, ptr %p
ret void
}

define half @return(ptr %p) nounwind {
; ALL-LABEL: return:
; ALL: .functype return (i32) -> (f32)
; ALL: .functype return (i32) -> (i32)
; ALL-NEXT: # %bb.0:
; ALL-NEXT: local.get $push2=, 0
; ALL-NEXT: i32.load16_u $push0=, 0($pop2)
; ALL-NEXT: call $push1=, __extendhfsf2, $pop0
; ALL-NEXT: return $pop1
; ALL-NEXT: local.get $push1=, 0
; ALL-NEXT: i32.load16_u $push0=, 0($pop1)
; ALL-NEXT: return $pop0
%r = load half, ptr %p
ret half %r
}
Expand Down Expand Up @@ -80,50 +78,28 @@ define dso_local float @loadf(ptr nocapture readonly %a) local_unnamed_addr noun
}

define dso_local void @stored(ptr nocapture %a, double %b) local_unnamed_addr nounwind {
; DEFISEL-LABEL: stored:
; DEFISEL: .functype stored (i32, f64) -> ()
; DEFISEL-NEXT: # %bb.0:
; DEFISEL-NEXT: local.get $push2=, 0
; DEFISEL-NEXT: local.get $push1=, 1
; DEFISEL-NEXT: call $push0=, __truncdfhf2, $pop1
; DEFISEL-NEXT: i32.store16 0($pop2), $pop0
; DEFISEL-NEXT: return
;
; FASTISEL-LABEL: stored:
; FASTISEL: .functype stored (i32, f64) -> ()
; FASTISEL-NEXT: # %bb.0:
; FASTISEL-NEXT: local.get $push4=, 0
; FASTISEL-NEXT: local.get $push3=, 1
; FASTISEL-NEXT: call $push2=, __truncdfhf2, $pop3
; FASTISEL-NEXT: i32.const $push1=, 65535
; FASTISEL-NEXT: i32.and $push0=, $pop2, $pop1
; FASTISEL-NEXT: i32.store16 0($pop4), $pop0
; FASTISEL-NEXT: return
; ALL-LABEL: stored:
; ALL: .functype stored (i32, f64) -> ()
; ALL-NEXT: # %bb.0:
; ALL-NEXT: local.get $push2=, 0
; ALL-NEXT: local.get $push1=, 1
; ALL-NEXT: call $push0=, __truncdfhf2, $pop1
; ALL-NEXT: i32.store16 0($pop2), $pop0
; ALL-NEXT: return
%x = tail call i16 @llvm.convert.to.fp16.f64(double %b)
store i16 %x, ptr %a, align 2
ret void
}

define dso_local void @storef(ptr nocapture %a, float %b) local_unnamed_addr nounwind {
; DEFISEL-LABEL: storef:
; DEFISEL: .functype storef (i32, f32) -> ()
; DEFISEL-NEXT: # %bb.0:
; DEFISEL-NEXT: local.get $push2=, 0
; DEFISEL-NEXT: local.get $push1=, 1
; DEFISEL-NEXT: call $push0=, __truncsfhf2, $pop1
; DEFISEL-NEXT: i32.store16 0($pop2), $pop0
; DEFISEL-NEXT: return
;
; FASTISEL-LABEL: storef:
; FASTISEL: .functype storef (i32, f32) -> ()
; FASTISEL-NEXT: # %bb.0:
; FASTISEL-NEXT: local.get $push4=, 0
; FASTISEL-NEXT: local.get $push3=, 1
; FASTISEL-NEXT: call $push2=, __truncsfhf2, $pop3
; FASTISEL-NEXT: i32.const $push1=, 65535
; FASTISEL-NEXT: i32.and $push0=, $pop2, $pop1
; FASTISEL-NEXT: i32.store16 0($pop4), $pop0
; FASTISEL-NEXT: return
; ALL-LABEL: storef:
; ALL: .functype storef (i32, f32) -> ()
; ALL-NEXT: # %bb.0:
; ALL-NEXT: local.get $push2=, 0
; ALL-NEXT: local.get $push1=, 1
; ALL-NEXT: call $push0=, __truncsfhf2, $pop1
; ALL-NEXT: i32.store16 0($pop2), $pop0
; ALL-NEXT: return
%x = tail call i16 @llvm.convert.to.fp16.f32(float %b)
store i16 %x, ptr %a, align 2
ret void
Expand Down Expand Up @@ -170,33 +146,20 @@ define void @test_bitcast_to_half(ptr %addr, i16 %in) nounwind {

define half @from_bits(i16 %x) nounwind {
; ALL-LABEL: from_bits:
; ALL: .functype from_bits (i32) -> (f32)
; ALL: .functype from_bits (i32) -> (i32)
; ALL-NEXT: # %bb.0:
; ALL-NEXT: local.get $push1=, 0
; ALL-NEXT: call $push0=, __extendhfsf2, $pop1
; ALL-NEXT: local.get $push0=, 0
; ALL-NEXT: return $pop0
%res = bitcast i16 %x to half
ret half %res
}

define i16 @to_bits(half %x) nounwind {
; DEFISEL-LABEL: to_bits:
; DEFISEL: .functype to_bits (f32) -> (i32)
; DEFISEL-NEXT: # %bb.0:
; DEFISEL-NEXT: local.get $push3=, 0
; DEFISEL-NEXT: call $push1=, __truncsfhf2, $pop3
; DEFISEL-NEXT: i32.const $push0=, 65535
; DEFISEL-NEXT: i32.and $push2=, $pop1, $pop0
; DEFISEL-NEXT: return $pop2
;
; FASTISEL-LABEL: to_bits:
; FASTISEL: .functype to_bits (f32) -> (i32)
; FASTISEL-NEXT: # %bb.0:
; FASTISEL-NEXT: local.get $push3=, 0
; FASTISEL-NEXT: call $push2=, __truncsfhf2, $pop3
; FASTISEL-NEXT: i32.const $push1=, 65535
; FASTISEL-NEXT: i32.and $push0=, $pop2, $pop1
; FASTISEL-NEXT: return $pop0
; ALL-LABEL: to_bits:
; ALL: .functype to_bits (i32) -> (i32)
; ALL-NEXT: # %bb.0:
; ALL-NEXT: local.get $push0=, 0
; ALL-NEXT: return $pop0
%res = bitcast half %x to i16
ret i16 %res
}
Expand Down Expand Up @@ -559,27 +522,35 @@ define float @test_sitofp_fadd_i32(i32 %a, ptr %b) nounwind {
; DEFISEL-LABEL: test_sitofp_fadd_i32:
; DEFISEL: .functype test_sitofp_fadd_i32 (i32, i32) -> (f32)
; DEFISEL-NEXT: # %bb.0:
; DEFISEL-NEXT: local.get $push6=, 1
; DEFISEL-NEXT: i32.load16_u $push1=, 0($pop6)
; DEFISEL-NEXT: local.get $push8=, 1
; DEFISEL-NEXT: i32.load16_u $push7=, 0($pop8)
; DEFISEL-NEXT: local.set 1, $pop7
; DEFISEL-NEXT: local.get $push9=, 0
; DEFISEL-NEXT: f32.convert_i32_s $push0=, $pop9
; DEFISEL-NEXT: call $push1=, __truncsfhf2, $pop0
; DEFISEL-NEXT: call $push2=, __extendhfsf2, $pop1
; DEFISEL-NEXT: local.get $push7=, 0
; DEFISEL-NEXT: f32.convert_i32_s $push0=, $pop7
; DEFISEL-NEXT: call $push3=, __truncsfhf2, $pop0
; DEFISEL-NEXT: call $push4=, __extendhfsf2, $pop3
; DEFISEL-NEXT: f32.add $push5=, $pop2, $pop4
; DEFISEL-NEXT: return $pop5
; DEFISEL-NEXT: local.get $push10=, 1
; DEFISEL-NEXT: call $push3=, __extendhfsf2, $pop10
; DEFISEL-NEXT: f32.add $push4=, $pop2, $pop3
; DEFISEL-NEXT: call $push5=, __truncsfhf2, $pop4
; DEFISEL-NEXT: call $push6=, __extendhfsf2, $pop5
; DEFISEL-NEXT: return $pop6
;
; FASTISEL-LABEL: test_sitofp_fadd_i32:
; FASTISEL: .functype test_sitofp_fadd_i32 (i32, i32) -> (f32)
; FASTISEL-NEXT: # %bb.0:
; FASTISEL-NEXT: local.get $push6=, 1
; FASTISEL-NEXT: i32.load16_u $push2=, 0($pop6)
; FASTISEL-NEXT: local.get $push8=, 1
; FASTISEL-NEXT: i32.load16_u $push7=, 0($pop8)
; FASTISEL-NEXT: local.set 1, $pop7
; FASTISEL-NEXT: local.get $push9=, 0
; FASTISEL-NEXT: f32.convert_i32_s $push1=, $pop9
; FASTISEL-NEXT: call $push2=, __truncsfhf2, $pop1
; FASTISEL-NEXT: call $push3=, __extendhfsf2, $pop2
; FASTISEL-NEXT: local.get $push7=, 0
; FASTISEL-NEXT: f32.convert_i32_s $push1=, $pop7
; FASTISEL-NEXT: call $push4=, __truncsfhf2, $pop1
; FASTISEL-NEXT: call $push5=, __extendhfsf2, $pop4
; FASTISEL-NEXT: f32.add $push0=, $pop3, $pop5
; FASTISEL-NEXT: local.get $push10=, 1
; FASTISEL-NEXT: call $push4=, __extendhfsf2, $pop10
; FASTISEL-NEXT: f32.add $push5=, $pop3, $pop4
; FASTISEL-NEXT: call $push6=, __truncsfhf2, $pop5
; FASTISEL-NEXT: call $push0=, __extendhfsf2, $pop6
; FASTISEL-NEXT: return $pop0
%tmp0 = load half, ptr %b
%tmp1 = sitofp i32 %a to half
Expand All @@ -590,17 +561,20 @@ define float @test_sitofp_fadd_i32(i32 %a, ptr %b) nounwind {

define half @chained_fp_ops(half %x) {
; ALL-LABEL: chained_fp_ops:
; ALL: .functype chained_fp_ops (f32) -> (f32)
; ALL: .functype chained_fp_ops (i32) -> (i32)
; ALL-NEXT: .local f32
; ALL-NEXT: # %bb.0: # %start
; ALL-NEXT: local.get $push6=, 0
; ALL-NEXT: call $push0=, __truncsfhf2, $pop6
; ALL-NEXT: call $push5=, __extendhfsf2, $pop0
; ALL-NEXT: local.tee $push4=, 0, $pop5
; ALL-NEXT: local.get $push7=, 0
; ALL-NEXT: f32.add $push1=, $pop4, $pop7
; ALL-NEXT: f32.const $push2=, 0x1p-1
; ALL-NEXT: f32.mul $push3=, $pop1, $pop2
; ALL-NEXT: return $pop3
; ALL-NEXT: local.get $push8=, 0
; ALL-NEXT: call $push7=, __extendhfsf2, $pop8
; ALL-NEXT: local.tee $push6=, 1, $pop7
; ALL-NEXT: local.get $push9=, 1
; ALL-NEXT: f32.add $push0=, $pop6, $pop9
; ALL-NEXT: call $push2=, __truncsfhf2, $pop0
; ALL-NEXT: call $push3=, __extendhfsf2, $pop2
; ALL-NEXT: f32.const $push1=, 0x1p-1
; ALL-NEXT: f32.mul $push4=, $pop3, $pop1
; ALL-NEXT: call $push5=, __truncsfhf2, $pop4
; ALL-NEXT: return $pop5
start:
%y = fmul half %x, 0xH4000
%z = fdiv half %y, 0xH4000
Expand All @@ -609,16 +583,15 @@ start:

define half @test_select_cc(half) nounwind {
; ALL-LABEL: test_select_cc:
; ALL: .functype test_select_cc (f32) -> (f32)
; ALL: .functype test_select_cc (i32) -> (i32)
; ALL-NEXT: # %bb.0:
; ALL-NEXT: f32.const $push4=, 0x1p0
; ALL-NEXT: i32.const $push4=, 15360
; ALL-NEXT: i32.const $push3=, 0
; ALL-NEXT: local.get $push6=, 0
; ALL-NEXT: call $push1=, __extendhfsf2, $pop6
; ALL-NEXT: f32.const $push0=, 0x0p0
; ALL-NEXT: local.get $push7=, 0
; ALL-NEXT: call $push1=, __truncsfhf2, $pop7
; ALL-NEXT: call $push2=, __extendhfsf2, $pop1
; ALL-NEXT: f32.const $push6=, 0x0p0
; ALL-NEXT: f32.ne $push3=, $pop2, $pop6
; ALL-NEXT: f32.select $push5=, $pop4, $pop0, $pop3
; ALL-NEXT: f32.ne $push2=, $pop1, $pop0
; ALL-NEXT: i32.select $push5=, $pop4, $pop3, $pop2
; ALL-NEXT: return $pop5
%2 = fcmp une half %0, 0xH0000
%3 = uitofp i1 %2 to half
Expand All @@ -627,27 +600,28 @@ define half @test_select_cc(half) nounwind {

define half @fabs(half %x) nounwind {
; ALL-LABEL: fabs:
; ALL: .functype fabs (f32) -> (f32)
; ALL: .functype fabs (i32) -> (i32)
; ALL-NEXT: # %bb.0:
; ALL-NEXT: local.get $push3=, 0
; ALL-NEXT: call $push0=, __truncsfhf2, $pop3
; ALL-NEXT: call $push1=, __extendhfsf2, $pop0
; ALL-NEXT: f32.abs $push2=, $pop1
; ALL-NEXT: return $pop2
; ALL-NEXT: local.get $push2=, 0
; ALL-NEXT: i32.const $push0=, 32767
; ALL-NEXT: i32.and $push1=, $pop2, $pop0
; ALL-NEXT: return $pop1
%a = call half @llvm.fabs.f16(half %x)
ret half %a
}

define half @fcopysign(half %x, half %y) nounwind {
; ALL-LABEL: fcopysign:
; ALL: .functype fcopysign (f32, f32) -> (f32)
; ALL: .functype fcopysign (i32, i32) -> (i32)
; ALL-NEXT: # %bb.0:
; ALL-NEXT: local.get $push3=, 0
; ALL-NEXT: call $push0=, __truncsfhf2, $pop3
; ALL-NEXT: call $push1=, __extendhfsf2, $pop0
; ALL-NEXT: local.get $push4=, 1
; ALL-NEXT: f32.copysign $push2=, $pop1, $pop4
; ALL-NEXT: return $pop2
; ALL-NEXT: local.get $push5=, 0
; ALL-NEXT: i32.const $push2=, 32767
; ALL-NEXT: i32.and $push3=, $pop5, $pop2
; ALL-NEXT: local.get $push6=, 1
; ALL-NEXT: i32.const $push0=, -32768
; ALL-NEXT: i32.and $push1=, $pop6, $pop0
; ALL-NEXT: i32.or $push4=, $pop3, $pop1
; ALL-NEXT: return $pop4
%a = call half @llvm.copysign.f16(half %x, half %y)
ret half %a
}
Loading
Loading