Skip to content

Commit

Permalink
Testpoints for new value transforms + code cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
jatin-bhateja committed Nov 22, 2024
1 parent 132878b commit 5f58eea
Show file tree
Hide file tree
Showing 20 changed files with 215 additions and 139 deletions.
39 changes: 32 additions & 7 deletions src/hotspot/cpu/x86/x86.ad
Original file line number Diff line number Diff line change
Expand Up @@ -4514,18 +4514,43 @@ instruct vReplS_reg(vec dst, rRegI src) %{
%}

#ifdef _LP64
instruct ReplS_imm(vec dst, immH con, rRegI rtmp) %{
predicate(VM_Version::supports_avx512_fp16() && Matcher::vector_element_basic_type(n) == T_SHORT);
instruct ReplH_imm(vec dst, immH con, rRegI rtmp) %{
match(Set dst (Replicate con));
effect(TEMP rtmp);
format %{ "replicateS $dst, $con" %}
format %{ "replicateH $dst, $con \t! using $rtmp as TEMP" %}
ins_encode %{
int vlen_enc = vector_length_encoding(this);
BasicType bt = Matcher::vector_element_basic_type(this);
assert(VM_Version::supports_avx512_fp16() && bt == T_SHORT, "");
__ movl($rtmp$$Register, $con$$constant);
__ evpbroadcastw($dst$$XMMRegister, $rtmp$$Register, vlen_enc);
%}
ins_pipe( pipe_slow );
%}

instruct ReplH_short_reg(vec dst, rRegI src) %{
predicate(VM_Version::supports_avx512_fp16() && Matcher::vector_element_basic_type(n) == T_SHORT);
match(Set dst (Replicate (ReinterpretS2HF src)));
format %{ "replicateH $dst, $src" %}
ins_encode %{
int vlen_enc = vector_length_encoding(this);
__ evpbroadcastw($dst$$XMMRegister, $src$$Register, vlen_enc);
%}
ins_pipe( pipe_slow );
%}

instruct ReplH_reg(vec dst, regF src, rRegI rtmp) %{
predicate(VM_Version::supports_avx512_fp16() && Matcher::vector_element_basic_type(n) == T_SHORT);
match(Set dst (Replicate src));
effect(TEMP rtmp);
format %{ "replicateH $dst, $src \t! using $rtmp as TEMP" %}
ins_encode %{
int vlen_enc = vector_length_encoding(this);
__ vmovw($rtmp$$Register, $src$$XMMRegister);
__ evpbroadcastw($dst$$XMMRegister, $rtmp$$Register, vlen_enc);
%}
ins_pipe( pipe_slow );
%}
#endif

instruct ReplS_mem(vec dst, memory mem) %{
Expand Down Expand Up @@ -10902,7 +10927,7 @@ instruct reinterpretH2S(rRegI dst, regF src)
ins_pipe(pipe_slow);
%}

instruct scalar_sqrt_fp16(regF dst, regF src)
instruct scalar_sqrt_fp16_reg(regF dst, regF src)
%{
match(Set dst (SqrtHF src));
format %{ "vsqrtsh $dst, $src" %}
Expand All @@ -10912,7 +10937,7 @@ instruct scalar_sqrt_fp16(regF dst, regF src)
ins_pipe(pipe_slow);
%}

instruct scalar_binOps_fp16(regF dst, regF src1, regF src2)
instruct scalar_binOps_fp16_reg(regF dst, regF src1, regF src2)
%{
match(Set dst (AddHF src1 src2));
match(Set dst (DivHF src1 src2));
Expand All @@ -10928,7 +10953,7 @@ instruct scalar_binOps_fp16(regF dst, regF src1, regF src2)
ins_pipe(pipe_slow);
%}

instruct scalar_fma_fp16(regF dst, regF src1, regF src2)
instruct scalar_fma_fp16_reg(regF dst, regF src1, regF src2)
%{
match(Set dst (FmaHF src2 (Binary dst src1)));
effect(DEF dst);
Expand Down Expand Up @@ -11008,7 +11033,7 @@ instruct vector_fma_fp16_reg(vec dst, vec src1, vec src2)
ins_pipe( pipe_slow );
%}

instruct vector_fmah_fp16_mem(vec dst, memory src1, vec src2)
instruct vector_fma_fp16_mem(vec dst, memory src1, vec src2)
%{
match(Set dst (FmaVHF src2 (Binary dst (VectorReinterpret (LoadVector src1)))));
effect(DEF dst);
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/adlc/output_h.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down
19 changes: 10 additions & 9 deletions src/hotspot/share/opto/addnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,15 +710,15 @@ Node *AddFNode::Ideal(PhaseGVN *phase, bool can_reshape) {
//=============================================================================
//------------------------------add_of_identity--------------------------------
// Check for addition of the identity
const Type *AddHFNode::add_of_identity( const Type *t1, const Type *t2 ) const {
const Type *AddHFNode::add_of_identity(const Type *t1, const Type *t2) const {
return nullptr;
}

//------------------------------add_ring---------------------------------------
// Supplied function returns the sum of the inputs.
// This also type-checks the inputs for sanity. Guaranteed never to
// be passed a TOP or BOTTOM type, these are filtered out by pre-check.
const Type *AddHFNode::add_ring( const Type *t0, const Type *t1 ) const {
const Type *AddHFNode::add_ring(const Type *t0, const Type *t1) const {
if (!t0->isa_half_float_constant() || !t1->isa_half_float_constant()) {
return bottom_type();
}
Expand Down Expand Up @@ -1601,7 +1601,7 @@ Node* MaxNode::Identity(PhaseGVN* phase) {
}

//------------------------------add_ring---------------------------------------
const Type* MinHFNode::add_ring(const Type* t0, const Type* t1 ) const {
const Type* MinHFNode::add_ring(const Type* t0, const Type* t1) const {
const TypeH* r0 = t0->isa_half_float_constant();
const TypeH* r1 = t1->isa_half_float_constant();
if (r0 == nullptr || r1 == nullptr) {
Expand Down Expand Up @@ -1676,9 +1676,9 @@ const Type* MinDNode::add_ring(const Type* t0, const Type* t1) const {
}

//------------------------------add_ring---------------------------------------
const Type* MaxFNode::add_ring(const Type* t0, const Type* t1) const {
const TypeF* r0 = t0->isa_float_constant();
const TypeF* r1 = t1->isa_float_constant();
const Type* MaxHFNode::add_ring(const Type* t0, const Type* t1) const {
const TypeH* r0 = t0->isa_half_float_constant();
const TypeH* r1 = t1->isa_half_float_constant();
if (r0 == nullptr || r1 == nullptr) {
return bottom_type();
}
Expand All @@ -1700,10 +1700,11 @@ const Type* MaxFNode::add_ring(const Type* t0, const Type* t1) const {
return (jint_cast(f0) > jint_cast(f1)) ? r0 : r1;
}


//------------------------------add_ring---------------------------------------
const Type* MaxHFNode::add_ring(const Type* t0, const Type* t1) const {
const TypeH* r0 = t0->isa_half_float_constant();
const TypeH* r1 = t1->isa_half_float_constant();
const Type* MaxFNode::add_ring(const Type* t0, const Type* t1) const {
const TypeF* r0 = t0->isa_float_constant();
const TypeF* r1 = t1->isa_float_constant();
if (r0 == nullptr || r1 == nullptr) {
return bottom_type();
}
Expand Down
10 changes: 5 additions & 5 deletions src/hotspot/share/opto/addnode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,12 @@ class AddDNode : public AddNode {
// Add 2 half-precision floats
class AddHFNode : public AddNode {
public:
AddHFNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}
AddHFNode(Node *in1, Node *in2) : AddNode(in1,in2) {}
virtual int Opcode() const;
virtual const Type *add_of_identity( const Type *t1, const Type *t2 ) const;
virtual const Type *add_ring( const Type *, const Type * ) const;
virtual const Type *add_id() const { return TypeH::ZERO; }
virtual const Type *bottom_type() const { return Type::HALF_FLOAT; }
virtual const Type* add_of_identity(const Type *t1, const Type *t2) const;
virtual const Type* add_ring(const Type*, const Type*) const;
virtual const Type* add_id() const { return TypeH::ZERO; }
virtual const Type* bottom_type() const { return Type::HALF_FLOAT; }
int max_opcode() const { return Op_MaxHF; }
int min_opcode() const { return Op_MinHF; }
virtual Node* Identity(PhaseGVN* phase) { return this; }
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/connode.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/connode.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/opto/constantTable.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -88,7 +88,7 @@ static int constant_size(ConstantTable::Constant* con) {
return type2aelembytes(con->type()) * con->get_array()->length();
}
switch (con->type()) {
case T_SHORT: return sizeof(jshort );
case T_SHORT: return sizeof(jint );
case T_INT: return sizeof(jint );
case T_LONG: return sizeof(jlong );
case T_FLOAT: return sizeof(jfloat );
Expand Down
21 changes: 20 additions & 1 deletion src/hotspot/share/opto/convertnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ Node* ConvF2HFNode::Ideal(PhaseGVN* phase, bool can_reshape) {
if (Float16NodeFactory::is_binary_oper(in(1)->Opcode()) &&
in(1)->in(1)->Opcode() == Op_ConvHF2F &&
in(1)->in(2)->Opcode() == Op_ConvHF2F) {
if (Matcher::match_rule_supported(in(1)->Opcode()) &&
if (Matcher::match_rule_supported(Float16NodeFactory::get_float16_binary_oper(in(1)->Opcode())) &&
Matcher::match_rule_supported(Op_ReinterpretS2HF) &&
Matcher::match_rule_supported(Op_ReinterpretHF2S)) {
Node* in1 = phase->transform(new ReinterpretS2HFNode(in(1)->in(1)->in(1)));
Expand Down Expand Up @@ -959,6 +959,25 @@ bool Float16NodeFactory::is_binary_oper(int opc) {
}
}

int Float16NodeFactory::get_float16_binary_oper(int opc) {
switch(opc) {
case Op_AddF:
return Op_AddHF;
case Op_SubF:
return Op_SubHF;
case Op_MulF:
return Op_MulHF;
case Op_DivF:
return Op_DivHF;
case Op_MaxF:
return Op_MaxHF;
case Op_MinF:
return Op_MinHF;
default:
return false;
}
}

Node* Float16NodeFactory::make(int opc, Node* c, Node* in1, Node* in2) {
switch(opc) {
case Op_AddF: return new AddHFNode(in1, in2);
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/opto/convertnode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ class RoundDoubleModeNode: public Node {
class Float16NodeFactory {
public:
static bool is_binary_oper(int opc);
static int get_float16_binary_oper(int opc);
static Node* make(int opc, Node* c, Node* in1, Node* in2);
};

Expand Down
52 changes: 26 additions & 26 deletions src/hotspot/share/opto/divnode.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -753,15 +753,15 @@ Node *DivFNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// prevent hoisting the divide above an unsafe test.
const Type* DivHFNode::Value(PhaseGVN* phase) const {
// Either input is TOP ==> the result is TOP
const Type *t1 = phase->type( in(1) );
const Type *t2 = phase->type( in(2) );
if( t1 == Type::TOP ) return Type::TOP;
if( t2 == Type::TOP ) return Type::TOP;
const Type* t1 = phase->type(in(1));
const Type* t2 = phase->type(in(2));
if(t1 == Type::TOP) return Type::TOP;
if(t2 == Type::TOP) return Type::TOP;

// Either input is BOTTOM ==> the result is the local BOTTOM
const Type *bot = bottom_type();
if( (t1 == bot) || (t2 == bot) ||
(t1 == Type::BOTTOM) || (t2 == Type::BOTTOM) )
const Type* bot = bottom_type();
if((t1 == bot) || (t2 == bot) ||
(t1 == Type::BOTTOM) || (t2 == Type::BOTTOM))
return bot;

// x/x == 1, we ignore 0/0.
Expand All @@ -772,20 +772,20 @@ const Type* DivHFNode::Value(PhaseGVN* phase) const {
return TypeH::ONE;
}

if( t2 == TypeH::ONE )
if(t2 == TypeH::ONE)
return t1;

// If divisor is a constant and not zero, divide them numbers
if( t1->base() == Type::HalfFloatCon &&
t2->base() == Type::HalfFloatCon &&
t2->getf() != 0.0 ) // could be negative zero
return TypeH::make( t1->getf()/t2->getf() );
if(t1->base() == Type::HalfFloatCon &&
t2->base() == Type::HalfFloatCon &&
t2->getf() != 0.0) // could be negative zero
return TypeH::make(t1->getf()/t2->getf());

// If the dividend is a constant zero
// Note: if t1 and t2 are zero then result is NaN (JVMS page 213)
// Test TypeF::ZERO is not sufficient as it could be negative zero

if( t1 == TypeH::ZERO && !g_isnan(t2->getf()) && t2->getf() != 0.0 )
if(t1 == TypeH::ZERO && !g_isnan(t2->getf()) && t2->getf() != 0.0)
return TypeH::ZERO;

// Otherwise we give up all hope
Expand All @@ -801,36 +801,36 @@ Node* DivHFNode::Identity(PhaseGVN* phase) {


//------------------------------Idealize---------------------------------------
Node *DivHFNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node *DivHFNode::Ideal(PhaseGVN* phase, bool can_reshape) {
if (in(0) && remove_dead_region(phase, can_reshape)) return this;
// Don't bother trying to transform a dead node
if( in(0) && in(0)->is_top() ) return nullptr;
if(in(0) && in(0)->is_top()) return nullptr;

const Type *t2 = phase->type( in(2) );
if( t2 == TypeH::ONE ) // Identity?
return nullptr; // Skip it
const Type* t2 = phase->type(in(2));
if(t2 == TypeH::ONE) // Identity?
return nullptr; // Skip it

const TypeH *tf = t2->isa_half_float_constant();
if( !tf ) return nullptr;
if( tf->base() != Type::HalfFloatCon ) return nullptr;
const TypeH* tf = t2->isa_half_float_constant();
if(!tf) return nullptr;
if(tf->base() != Type::HalfFloatCon) return nullptr;

// Check for out of range values
if( tf->is_nan() || !tf->is_finite() ) return nullptr;
if(tf->is_nan() || !tf->is_finite()) return nullptr;

// Get the value
float f = tf->getf();
int exp;

// Only for special case of dividing by a power of 2
if( frexp((double)f, &exp) != 0.5 ) return nullptr;
if(frexp((double)f, &exp) != 0.5) return nullptr;

// Limit the range of acceptable exponents
if( exp < -14 || exp > 15 ) return nullptr;
if(exp < -14 || exp > 15) return nullptr;

// Compute the reciprocal
float reciprocal = ((float)1.0) / f;

assert( frexp((double)reciprocal, &exp) == 0.5, "reciprocal should be power of 2" );
assert(frexp((double)reciprocal, &exp) == 0.5, "reciprocal should be power of 2");

// return multiplication by the reciprocal
return (new MulHFNode(in(1), phase->makecon(TypeH::make(reciprocal))));
Expand Down
8 changes: 4 additions & 4 deletions src/hotspot/share/opto/divnode.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -82,12 +82,12 @@ class DivFNode : public Node {
// Half float division
class DivHFNode : public Node {
public:
DivHFNode( Node *c, Node *dividend, Node *divisor ) : Node(c, dividend, divisor) {}
DivHFNode(Node* c, Node* dividend, Node* divisor) : Node(c, dividend, divisor) {}
virtual int Opcode() const;
virtual Node* Identity(PhaseGVN* phase);
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
virtual const Type* Value(PhaseGVN* phase) const;
virtual const Type *bottom_type() const { return Type::HALF_FLOAT; }
virtual const Type* bottom_type() const { return Type::HALF_FLOAT; }
virtual uint ideal_reg() const { return Op_RegF; }
};

Expand Down
Loading

0 comments on commit 5f58eea

Please sign in to comment.