forked from OSchip/llvm-project
[WebAssembly] Fix fneg lowering
Summary: Subtraction from zero and floating point negation do not have the same semantics, so fix lowering. Reviewers: aheejin, dschuff Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D52948 llvm-svn: 344107
This commit is contained in:
parent
5d900954bd
commit
108e98ec32
|
@ -400,6 +400,9 @@ multiclass SIMDBinaryInt<SDNode node, string name, bits<32> baseInst> {
|
|||
defm "" : SIMDBinary<v2i64, "i64x2", node, name, !add(baseInst, 3)>;
|
||||
}
|
||||
|
||||
// Integer vector negation
|
||||
def ivneg : PatFrag<(ops node:$in), (sub immAllZerosV, node:$in)>;
|
||||
|
||||
// Integer addition: add
|
||||
let isCommutable = 1 in
|
||||
defm ADD : SIMDBinaryInt<add, "add", 24>;
|
||||
|
@ -411,29 +414,18 @@ defm SUB : SIMDBinaryInt<sub, "sub", 28>;
|
|||
defm MUL : SIMDBinaryIntNoI64x2<mul, "mul", 32>;
|
||||
|
||||
// Integer negation: neg
|
||||
multiclass SIMDNeg<ValueType vec_t, string vec, PatFrag splat_pat,
|
||||
ValueType lane_t, SDNode node, dag lane, bits<32> simdop> {
|
||||
defm NEG_#vec_t : SIMD_I<(outs V128:$dst), (ins V128:$vec),
|
||||
(outs), (ins),
|
||||
[(set
|
||||
(vec_t V128:$dst),
|
||||
(vec_t (node
|
||||
(vec_t (splat_pat lane)),
|
||||
(vec_t V128:$vec)
|
||||
))
|
||||
multiclass SIMDNeg<ValueType vec_t, string vec, SDNode neg, bits<32> simdop> {
|
||||
defm NEG_#vec_t : SIMD_I<(outs V128:$dst), (ins V128:$vec), (outs), (ins),
|
||||
[(set (vec_t V128:$dst),
|
||||
(vec_t (neg (vec_t V128:$vec)))
|
||||
)],
|
||||
vec#".neg\t$dst, $vec", vec#".neg", simdop>;
|
||||
}
|
||||
|
||||
multiclass SIMDNegInt<ValueType vec_t, string vec, PatFrag splat_pat,
|
||||
ValueType lane_t, bits<32> simdop> {
|
||||
defm "" : SIMDNeg<vec_t, vec, splat_pat, lane_t, sub, (lane_t 0), simdop>;
|
||||
}
|
||||
|
||||
defm "" : SIMDNegInt<v16i8, "i8x16", splat16, i32, 36>;
|
||||
defm "" : SIMDNegInt<v8i16, "i16x8", splat8, i32, 37>;
|
||||
defm "" : SIMDNegInt<v4i32, "i32x4", splat4, i32, 38>;
|
||||
defm "" : SIMDNegInt<v2i64, "i64x2", splat2, i64, 39>;
|
||||
defm "" : SIMDNeg<v16i8, "i8x16", ivneg, 36>;
|
||||
defm "" : SIMDNeg<v8i16, "i16x8", ivneg, 37>;
|
||||
defm "" : SIMDNeg<v4i32, "i32x4", ivneg, 38>;
|
||||
defm "" : SIMDNeg<v2i64, "i64x2", ivneg, 39>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Saturating integer arithmetic
|
||||
|
@ -718,15 +710,8 @@ def : StorePatExternSymOffOnly<vec_t, store, !cast<NI>("STORE_"#vec_t)>;
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Negation: neg
|
||||
def fpimm0 : FPImmLeaf<fAny, [{ return Imm.isExactlyValue(+0.0); }]>;
|
||||
multiclass SIMDNegFP<ValueType vec_t, string vec, PatFrag splat_pat,
|
||||
ValueType lane_t, bits<32> simdop> {
|
||||
defm "" : SIMDNeg<vec_t, vec, splat_pat, lane_t, fsub, (lane_t fpimm0),
|
||||
simdop>;
|
||||
}
|
||||
|
||||
defm "" : SIMDNegFP<v4f32, "f32x4", splat4, f32, 125>;
|
||||
defm "" : SIMDNegFP<v2f64, "f64x2", splat2, f64, 126>;
|
||||
defm "" : SIMDNeg<v4f32, "f32x4", fneg, 125>;
|
||||
defm "" : SIMDNeg<v2f64, "f64x2", fneg, 126>;
|
||||
|
||||
// Absolute value: abs
|
||||
multiclass SIMDAbs<ValueType vec_t, string vec, bits<32> simdop> {
|
||||
|
|
|
@ -748,7 +748,8 @@ define <2 x i64> @bitselect_v2i64(<2 x i64> %c, <2 x i64> %v1, <2 x i64> %v2) {
|
|||
; SIMD128-NEXT: f32x4.neg $push[[R:[0-9]+]]=, $0{{$}}
|
||||
; SIMD128-NEXT: return $pop[[R]]{{$}}
|
||||
define <4 x float> @neg_v4f32(<4 x float> %x) {
|
||||
%a = fsub <4 x float> <float 0., float 0., float 0., float 0.>, %x
|
||||
; nsz makes this semantically equivalent to flipping sign bit
|
||||
%a = fsub nsz <4 x float> <float 0.0, float 0.0, float 0.0, float 0.0>, %x
|
||||
ret <4 x float> %a
|
||||
}
|
||||
|
||||
|
@ -830,7 +831,8 @@ define <4 x float> @sqrt_v4f32(<4 x float> %x) {
|
|||
; SIMD128-NEXT: f64x2.neg $push[[R:[0-9]+]]=, $0{{$}}
|
||||
; SIMD128-NEXT: return $pop[[R]]{{$}}
|
||||
define <2 x double> @neg_v2f64(<2 x double> %x) {
|
||||
%a = fsub <2 x double> <double 0., double 0.>, %x
|
||||
; nsz makes this semantically equivalent to flipping sign bit
|
||||
%a = fsub nsz <2 x double> <double 0., double 0.>, %x
|
||||
ret <2 x double> %a
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue