8282162: [vector] Optimize integral vector negation API

Reviewed-by: jiefu, psandoz, njian
This commit is contained in:
Xiaohong Gong 2022-03-30 01:36:51 +00:00 committed by Jie Fu
parent bfd9c2b30f
commit d06685680c
15 changed files with 301 additions and 51 deletions

View File

@ -4266,6 +4266,47 @@ instruct vsqrt2D(vecX dst, vecX src)
// --------------------------------- NEG --------------------------------------
instruct vnegID(vecD dst, vecD src)
%{
predicate(n->as_Vector()->length_in_bytes() < 16);
match(Set dst (NegVI src));
ins_cost(INSN_COST);
format %{ "negr $dst, $src\t# vector (8B/4H/2S)" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this);
Assembler::SIMD_Arrangement size = __ esize2arrangement((unsigned)type2aelembytes(bt), false);
__ negr(as_FloatRegister($dst$$reg), size, as_FloatRegister($src$$reg));
%}
ins_pipe(vunop_fp64);
%}
instruct vnegIX(vecX dst, vecX src)
%{
predicate(n->as_Vector()->length_in_bytes() == 16);
match(Set dst (NegVI src));
ins_cost(INSN_COST);
format %{ "negr $dst, $src\t# vector (16B/8H/4S)" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this);
Assembler::SIMD_Arrangement size = __ esize2arrangement((unsigned)type2aelembytes(bt), true);
__ negr(as_FloatRegister($dst$$reg), size, as_FloatRegister($src$$reg));
%}
ins_pipe(vunop_fp128);
%}
instruct vneg2L(vecX dst, vecX src)
%{
predicate(n->as_Vector()->length() == 2);
match(Set dst (NegVL src));
ins_cost(INSN_COST);
format %{ "negr $dst,$src\t# vector (2D)" %}
ins_encode %{
__ negr(as_FloatRegister($dst$$reg), __ T2D,
as_FloatRegister($src$$reg));
%}
ins_pipe(vunop_fp128);
%}
instruct vneg2F(vecD dst, vecD src)
%{
predicate(n->as_Vector()->length() == 2);

View File

@ -1923,20 +1923,39 @@ VSQRT(fsqrt, 4, F, X, S)
VSQRT(fsqrt, 2, D, X, D)
// --------------------------------- NEG --------------------------------------
define(`VNEGI', `
instruct vnegI$1(vec$1 dst, vec$1 src)
%{
predicate(n->as_Vector()->length_in_bytes() ifelse($1, D, <, ==) 16);
match(Set dst (NegVI src));
ins_cost(INSN_COST);
format %{ "negr $dst, $src\t# vector ($2)" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this);
Assembler::SIMD_Arrangement size = __ esize2arrangement((unsigned)type2aelembytes(bt), ifelse($1, D, false, true));
__ negr(as_FloatRegister($dst$$reg), size, as_FloatRegister($src$$reg));
%}
ins_pipe(vunop_fp`'ifelse($1, D, 64, 128));
%}')dnl
dnl $1 $2
VNEGI(D, 8B/4H/2S)
VNEGI(X, 16B/8H/4S)
dnl
define(`VNEG', `
instruct vneg$2$3`'(vec$4 dst, vec$4 src)
%{
predicate(n->as_Vector()->length() == $2);
match(Set dst (NegV$3 src));
ins_cost(INSN_COST * 3);
ins_cost(INSN_COST`'ifelse($3, L, `',` * 3'));
format %{ "$1 $dst,$src\t# vector ($2$5)" %}
ins_encode %{
__ $1(as_FloatRegister($dst$$reg), __ T$2`'ifelse($5, L, D, $5),
__ $1(as_FloatRegister($dst$$reg), __ T$2$5,
as_FloatRegister($src$$reg));
%}
ins_pipe(vunop_fp`'ifelse($4, D, 64, 128));
%}')dnl
dnl $1 $2 $3 $4 $5
VNEG(negr, 2, L, X, D)
VNEG(fneg, 2, F, D, S)
VNEG(fneg, 4, F, X, S)
VNEG(fneg, 2, D, X, D)

View File

@ -1936,7 +1936,34 @@ instruct vmulD_masked(vReg dst_src1, vReg src2, pRegGov pg) %{
ins_pipe(pipe_slow);
%}
// vector fneg
// vector neg
instruct vnegI(vReg dst, vReg src) %{
predicate(UseSVE > 0 &&
!n->as_Vector()->is_predicated_vector());
match(Set dst (NegVI src));
ins_cost(SVE_COST);
format %{ "sve_neg $dst, $src\t# vector (sve) (B/H/S)" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this);
__ sve_neg(as_FloatRegister($dst$$reg), __ elemType_to_regVariant(bt),
ptrue, as_FloatRegister($src$$reg));
%}
ins_pipe(pipe_slow);
%}
instruct vnegL(vReg dst, vReg src) %{
predicate(UseSVE > 0 &&
!n->as_Vector()->is_predicated_vector());
match(Set dst (NegVL src));
ins_cost(SVE_COST);
format %{ "sve_neg $dst, $src\t# vector (sve) (D)" %}
ins_encode %{
__ sve_neg(as_FloatRegister($dst$$reg), __ D,
ptrue, as_FloatRegister($src$$reg));
%}
ins_pipe(pipe_slow);
%}
instruct vnegF(vReg dst, vReg src) %{
predicate(UseSVE > 0 &&
@ -1964,7 +1991,34 @@ instruct vnegD(vReg dst, vReg src) %{
ins_pipe(pipe_slow);
%}
// vector fneg - predicated
// vector neg - predicated
instruct vnegI_masked(vReg dst_src, pRegGov pg) %{
predicate(UseSVE > 0);
match(Set dst_src (NegVI dst_src pg));
ins_cost(SVE_COST);
format %{ "sve_neg $dst_src, $pg, $dst_src\t# vector (sve) (B/H/S)" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this);
__ sve_neg(as_FloatRegister($dst_src$$reg), __ elemType_to_regVariant(bt),
as_PRegister($pg$$reg),
as_FloatRegister($dst_src$$reg));
%}
ins_pipe(pipe_slow);
%}
instruct vnegL_masked(vReg dst_src, pRegGov pg) %{
predicate(UseSVE > 0);
match(Set dst_src (NegVL dst_src pg));
ins_cost(SVE_COST);
format %{ "sve_neg $dst_src, $pg, $dst_src\t# vector (sve) (D)" %}
ins_encode %{
__ sve_neg(as_FloatRegister($dst_src$$reg), __ D,
as_PRegister($pg$$reg),
as_FloatRegister($dst_src$$reg));
%}
ins_pipe(pipe_slow);
%}
instruct vnegF_masked(vReg dst_src, pRegGov pg) %{
predicate(UseSVE > 0);

View File

@ -524,8 +524,10 @@ instruct $1(vReg dst, vReg src) %{
match(Set dst ($2 src));
ins_cost(SVE_COST);
format %{ "$4 $dst, $src\t# vector (sve) ($3)" %}
ins_encode %{
__ $4(as_FloatRegister($dst$$reg), __ $3,
ins_encode %{dnl
ifelse($1, `vnegI', `
BasicType bt = Matcher::vector_element_basic_type(this);', `')
__ $4(as_FloatRegister($dst$$reg), ifelse($1, `vnegI', `__ elemType_to_regVariant(bt)', `__ $3'),
ptrue, as_FloatRegister($src$$reg));
%}
ins_pipe(pipe_slow);
@ -548,8 +550,10 @@ instruct $1_masked(vReg dst_src, pRegGov pg) %{
match(Set dst_src ($2 dst_src pg));
ins_cost(SVE_COST);
format %{ "$4 $dst_src, $pg, $dst_src\t# vector (sve) ($3)" %}
ins_encode %{
__ $4(as_FloatRegister($dst_src$$reg), __ $3,
ins_encode %{dnl
ifelse($1, `vnegI', `
BasicType bt = Matcher::vector_element_basic_type(this);', `')
__ $4(as_FloatRegister($dst_src$$reg), ifelse($1, `vnegI', `__ elemType_to_regVariant(bt)', `__ $3'),
as_PRegister($pg$$reg),
as_FloatRegister($dst_src$$reg));
%}
@ -1091,11 +1095,15 @@ BINARY_OP_PREDICATE(vmulL, MulVL, D, sve_mul)
BINARY_OP_PREDICATE(vmulF, MulVF, S, sve_fmul)
BINARY_OP_PREDICATE(vmulD, MulVD, D, sve_fmul)
// vector fneg
// vector neg
UNARY_OP_TRUE_PREDICATE(vnegI, NegVI, B/H/S, sve_neg)
UNARY_OP_TRUE_PREDICATE(vnegL, NegVL, D, sve_neg)
UNARY_OP_TRUE_PREDICATE(vnegF, NegVF, S, sve_fneg)
UNARY_OP_TRUE_PREDICATE(vnegD, NegVD, D, sve_fneg)
// vector fneg - predicated
// vector neg - predicated
UNARY_OP_PREDICATE(vnegI, NegVI, B/H/S, sve_neg)
UNARY_OP_PREDICATE(vnegL, NegVL, D, sve_neg)
UNARY_OP_PREDICATE(vnegF, NegVF, S, sve_fneg)
UNARY_OP_PREDICATE(vnegD, NegVD, D, sve_fneg)

View File

@ -4212,7 +4212,7 @@ bool MatchRule::is_vector() const {
"CMoveVD", "CMoveVF",
"DivVF","DivVD",
"AbsVB","AbsVS","AbsVI","AbsVL","AbsVF","AbsVD",
"NegVF","NegVD","NegVI",
"NegVF","NegVD","NegVI","NegVL",
"SqrtVD","SqrtVF",
"AndV" ,"XorV" ,"OrV",
"MaxV", "MinV",

View File

@ -386,6 +386,7 @@ macro(AbsVL)
macro(AbsVF)
macro(AbsVD)
macro(NegVI)
macro(NegVL)
macro(NegVF)
macro(NegVD)
macro(SqrtVD)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2022, 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
@ -199,6 +199,16 @@ bool LibraryCallKit::arch_supports_vector(int sopc, int num_elem, BasicType type
tty->print_cr(" ** Rejected vector op (%s,%s,%d) because architecture does not support variable vector shifts",
NodeClassNames[sopc], type2name(type), num_elem);
}
#endif
return false;
}
} else if (VectorNode::is_vector_integral_negate(sopc)) {
if (!VectorNode::is_vector_integral_negate_supported(sopc, num_elem, type, false)) {
#ifndef PRODUCT
if (C->print_intrinsics()) {
tty->print_cr(" ** Rejected vector op (%s,%s,%d) because architecture does not support integral vector negate",
NodeClassNames[sopc], type2name(type), num_elem);
}
#endif
return false;
}
@ -277,8 +287,16 @@ bool LibraryCallKit::arch_supports_vector(int sopc, int num_elem, BasicType type
}
if ((mask_use_type & VecMaskUsePred) != 0) {
if (!Matcher::has_predicated_vectors() ||
!Matcher::match_rule_supported_vector_masked(sopc, num_elem, type)) {
bool is_supported = false;
if (Matcher::has_predicated_vectors()) {
if (VectorNode::is_vector_integral_negate(sopc)) {
is_supported = VectorNode::is_vector_integral_negate_supported(sopc, num_elem, type, true);
} else {
is_supported = Matcher::match_rule_supported_vector_masked(sopc, num_elem, type);
}
}
if (!is_supported) {
#ifndef PRODUCT
if (C->print_intrinsics()) {
tty->print_cr("Rejected vector mask predicate using (%s,%s,%d) because architecture does not support it",

View File

@ -135,7 +135,14 @@ int VectorNode::opcode(int sopc, BasicType bt) {
case Op_AbsD:
return (bt == T_DOUBLE ? Op_AbsVD : 0);
case Op_NegI:
return (bt == T_INT ? Op_NegVI : 0);
switch (bt) {
case T_BYTE:
case T_SHORT:
case T_INT: return Op_NegVI;
default: return 0;
}
case Op_NegL:
return (bt == T_LONG ? Op_NegVL : 0);
case Op_NegF:
return (bt == T_FLOAT ? Op_NegVF : 0);
case Op_NegD:
@ -275,6 +282,9 @@ bool VectorNode::implemented(int opc, uint vlen, BasicType bt) {
if (VectorNode::is_vector_rotate(vopc)) {
return is_vector_rotate_supported(vopc, vlen, bt);
}
if (VectorNode::is_vector_integral_negate(vopc)) {
return is_vector_integral_negate_supported(vopc, vlen, bt, false);
}
return vopc > 0 && Matcher::match_rule_supported_vector(vopc, vlen, bt);
}
return false;
@ -349,6 +359,38 @@ bool VectorNode::is_vector_rotate_supported(int vopc, uint vlen, BasicType bt) {
}
}
// Check whether the architecture supports the vector negate instructions. If not, then check
// whether the alternative vector nodes used to implement vector negation are supported.
// Return false if neither of them is supported.
bool VectorNode::is_vector_integral_negate_supported(int opc, uint vlen, BasicType bt, bool use_predicate) {
if (!use_predicate) {
// Check whether the NegVI/L is supported by the architecture.
if (Matcher::match_rule_supported_vector(opc, vlen, bt)) {
return true;
}
// Negate is implemented with "(SubVI/L (ReplicateI/L 0) src)", if NegVI/L is not supported.
int sub_opc = (bt == T_LONG) ? Op_SubL : Op_SubI;
if (Matcher::match_rule_supported_vector(VectorNode::opcode(sub_opc, bt), vlen, bt) &&
Matcher::match_rule_supported_vector(VectorNode::replicate_opcode(bt), vlen, bt)) {
return true;
}
} else {
// Check whether the predicated NegVI/L is supported by the architecture.
if (Matcher::match_rule_supported_vector_masked(opc, vlen, bt)) {
return true;
}
// Predicated negate is implemented with "(AddVI/L (XorV src (ReplicateI/L -1)) (ReplicateI/L 1))",
// if predicated NegVI/L is not supported.
int add_opc = (bt == T_LONG) ? Op_AddL : Op_AddI;
if (Matcher::match_rule_supported_vector_masked(Op_XorV, vlen, bt) &&
Matcher::match_rule_supported_vector_masked(VectorNode::opcode(add_opc, bt), vlen, bt) &&
Matcher::match_rule_supported_vector(VectorNode::replicate_opcode(bt), vlen, bt)) {
return true;
}
}
return false;
}
bool VectorNode::is_shift_opcode(int opc) {
switch (opc) {
case Op_LShiftI:
@ -536,6 +578,7 @@ VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, const TypeVect* vt, b
case Op_AbsVL: return new AbsVLNode(n1, vt);
case Op_NegVI: return new NegVINode(n1, vt);
case Op_NegVL: return new NegVLNode(n1, vt);
case Op_NegVF: return new NegVFNode(n1, vt);
case Op_NegVD: return new NegVDNode(n1, vt);
@ -667,6 +710,10 @@ bool VectorNode::is_vector_rotate(int opc) {
}
}
bool VectorNode::is_vector_integral_negate(int opc) {
return opc == Op_NegVI || opc == Op_NegVL;
}
bool VectorNode::is_vector_shift(int opc) {
assert(opc > _last_machine_leaf && opc < _last_opcode, "invalid opcode");
switch (opc) {
@ -1541,6 +1588,69 @@ Node* VectorLongToMaskNode::Ideal(PhaseGVN* phase, bool can_reshape) {
return NULL;
}
// Generate other vector nodes to implement the masked/non-masked vector negation.
Node* NegVNode::degenerate_integral_negate(PhaseGVN* phase, bool is_predicated) {
const TypeVect* vt = vect_type();
BasicType bt = vt->element_basic_type();
uint vlen = length();
// Transformation for predicated NegVI/L
if (is_predicated) {
// (NegVI/L src m) ==> (AddVI/L (XorV src (ReplicateI/L -1) m) (ReplicateI/L 1) m)
Node* const_minus_one = NULL;
Node* const_one = NULL;
int add_opc;
if (bt == T_LONG) {
const_minus_one = phase->longcon(-1L);
const_one = phase->longcon(1L);
add_opc = Op_AddL;
} else {
const_minus_one = phase->intcon(-1);
const_one = phase->intcon(1);
add_opc = Op_AddI;
}
const_minus_one = phase->transform(VectorNode::scalar2vector(const_minus_one, vlen, Type::get_const_basic_type(bt)));
Node* xorv = VectorNode::make(Op_XorV, in(1), const_minus_one, vt);
xorv->add_req(in(2));
xorv->add_flag(Node::Flag_is_predicated_vector);
phase->transform(xorv);
const_one = phase->transform(VectorNode::scalar2vector(const_one, vlen, Type::get_const_basic_type(bt)));
Node* addv = VectorNode::make(VectorNode::opcode(add_opc, bt), xorv, const_one, vt);
addv->add_req(in(2));
addv->add_flag(Node::Flag_is_predicated_vector);
return addv;
}
// NegVI/L ==> (SubVI/L (ReplicateI/L 0) src)
Node* const_zero = NULL;
int sub_opc;
if (bt == T_LONG) {
const_zero = phase->longcon(0L);
sub_opc = Op_SubL;
} else {
const_zero = phase->intcon(0);
sub_opc = Op_SubI;
}
const_zero = phase->transform(VectorNode::scalar2vector(const_zero, vlen, Type::get_const_basic_type(bt)));
return VectorNode::make(VectorNode::opcode(sub_opc, bt), const_zero, in(1), vt);
}
Node* NegVNode::Ideal(PhaseGVN* phase, bool can_reshape) {
BasicType bt = vect_type()->element_basic_type();
uint vlen = length();
int opc = Opcode();
if (is_vector_integral_negate(opc)) {
if (is_predicated_vector()) {
if (!Matcher::match_rule_supported_vector_masked(opc, vlen, bt)) {
return degenerate_integral_negate(phase, true);
}
} else if (!Matcher::match_rule_supported_vector(opc, vlen, bt)) {
return degenerate_integral_negate(phase, false);
}
}
return NULL;
}
#ifndef PRODUCT
void VectorBoxAllocateNode::dump_spec(outputStream *st) const {
CallStaticJavaNode::dump_spec(st);

View File

@ -97,6 +97,7 @@ class VectorNode : public TypeNode {
static bool is_roundopD(Node* n);
static bool is_scalar_rotate(Node* n);
static bool is_vector_rotate_supported(int opc, uint vlen, BasicType bt);
static bool is_vector_integral_negate_supported(int opc, uint vlen, BasicType bt, bool use_predicate);
static bool is_invariant_vector(Node* n);
static bool is_all_ones_vector(Node* n);
static bool is_vector_bitwise_not_pattern(Node* n);
@ -109,6 +110,7 @@ class VectorNode : public TypeNode {
static bool is_vector_shift(int opc);
static bool is_vector_shift_count(int opc);
static bool is_vector_rotate(int opc);
static bool is_vector_integral_negate(int opc);
static bool is_vector_shift(Node* n) {
return is_vector_shift(n->Opcode());
@ -474,27 +476,47 @@ class AbsVDNode : public VectorNode {
virtual int Opcode() const;
};
//------------------------------NegVINode--------------------------------------
// Vector Neg int
class NegVINode : public VectorNode {
//------------------------------NegVNode---------------------------------------
// Vector Neg parent class (not for code generation).
class NegVNode : public VectorNode {
public:
NegVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
NegVNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
virtual int Opcode() const = 0;
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
private:
Node* degenerate_integral_negate(PhaseGVN* phase, bool is_predicated);
};
//------------------------------NegVINode--------------------------------------
// Vector Neg byte/short/int
class NegVINode : public NegVNode {
public:
NegVINode(Node* in, const TypeVect* vt) : NegVNode(in, vt) {}
virtual int Opcode() const;
};
//------------------------------NegVLNode--------------------------------------
// Vector Neg long
class NegVLNode : public NegVNode {
public:
NegVLNode(Node* in, const TypeVect* vt) : NegVNode(in, vt) {}
virtual int Opcode() const;
};
//------------------------------NegVFNode--------------------------------------
// Vector Neg float
class NegVFNode : public VectorNode {
class NegVFNode : public NegVNode {
public:
NegVFNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
NegVFNode(Node* in, const TypeVect* vt) : NegVNode(in, vt) {}
virtual int Opcode() const;
};
//------------------------------NegVDNode--------------------------------------
// Vector Neg double
class NegVDNode : public VectorNode {
class NegVDNode : public NegVNode {
public:
NegVDNode(Node* in, const TypeVect* vt) : VectorNode(in,vt) {}
NegVDNode(Node* in, const TypeVect* vt) : NegVNode(in, vt) {}
virtual int Opcode() const;
};

View File

@ -1757,9 +1757,11 @@
declare_c2_type(MulVFNode, VectorNode) \
declare_c2_type(MulReductionVFNode, ReductionNode) \
declare_c2_type(MulVDNode, VectorNode) \
declare_c2_type(NegVINode, VectorNode) \
declare_c2_type(NegVFNode, VectorNode) \
declare_c2_type(NegVDNode, VectorNode) \
declare_c2_type(NegVNode, VectorNode) \
declare_c2_type(NegVINode, NegVNode) \
declare_c2_type(NegVLNode, NegVNode) \
declare_c2_type(NegVFNode, NegVNode) \
declare_c2_type(NegVDNode, NegVNode) \
declare_c2_type(FmaVDNode, VectorNode) \
declare_c2_type(FmaVFNode, VectorNode) \
declare_c2_type(CMoveVFNode, VectorNode) \

View File

@ -573,9 +573,6 @@ public abstract class ByteVector extends AbstractVector<Byte> {
}
if (op == NOT) {
return broadcast(-1).lanewise(XOR, this);
} else if (op == NEG) {
// FIXME: Support this in the JIT.
return broadcast(0).lanewise(SUB, this);
}
}
int opc = opCode(op);
@ -604,8 +601,6 @@ public abstract class ByteVector extends AbstractVector<Byte> {
}
if (op == NOT) {
return lanewise(XOR, broadcast(-1), m);
} else if (op == NEG) {
return lanewise(NOT, m).lanewise(ADD, broadcast(1), m);
}
}
int opc = opCode(op);

View File

@ -573,9 +573,6 @@ public abstract class IntVector extends AbstractVector<Integer> {
}
if (op == NOT) {
return broadcast(-1).lanewise(XOR, this);
} else if (op == NEG) {
// FIXME: Support this in the JIT.
return broadcast(0).lanewise(SUB, this);
}
}
int opc = opCode(op);
@ -604,8 +601,6 @@ public abstract class IntVector extends AbstractVector<Integer> {
}
if (op == NOT) {
return lanewise(XOR, broadcast(-1), m);
} else if (op == NEG) {
return lanewise(NOT, m).lanewise(ADD, broadcast(1), m);
}
}
int opc = opCode(op);

View File

@ -531,9 +531,6 @@ public abstract class LongVector extends AbstractVector<Long> {
}
if (op == NOT) {
return broadcast(-1).lanewise(XOR, this);
} else if (op == NEG) {
// FIXME: Support this in the JIT.
return broadcast(0).lanewise(SUB, this);
}
}
int opc = opCode(op);
@ -562,8 +559,6 @@ public abstract class LongVector extends AbstractVector<Long> {
}
if (op == NOT) {
return lanewise(XOR, broadcast(-1), m);
} else if (op == NEG) {
return lanewise(NOT, m).lanewise(ADD, broadcast(1), m);
}
}
int opc = opCode(op);

View File

@ -573,9 +573,6 @@ public abstract class ShortVector extends AbstractVector<Short> {
}
if (op == NOT) {
return broadcast(-1).lanewise(XOR, this);
} else if (op == NEG) {
// FIXME: Support this in the JIT.
return broadcast(0).lanewise(SUB, this);
}
}
int opc = opCode(op);
@ -604,8 +601,6 @@ public abstract class ShortVector extends AbstractVector<Short> {
}
if (op == NOT) {
return lanewise(XOR, broadcast(-1), m);
} else if (op == NEG) {
return lanewise(NOT, m).lanewise(ADD, broadcast(1), m);
}
}
int opc = opCode(op);

View File

@ -596,9 +596,6 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
#if[BITWISE]
if (op == NOT) {
return broadcast(-1).lanewise(XOR, this);
} else if (op == NEG) {
// FIXME: Support this in the JIT.
return broadcast(0).lanewise(SUB, this);
}
#end[BITWISE]
}
@ -629,8 +626,6 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
#if[BITWISE]
if (op == NOT) {
return lanewise(XOR, broadcast(-1), m);
} else if (op == NEG) {
return lanewise(NOT, m).lanewise(ADD, broadcast(1), m);
}
#end[BITWISE]
}