wazevo: fuzz, select does not return the correct value for vectors (#1814)
Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
This commit is contained in:
@@ -1873,21 +1873,31 @@ func (m *machine) lowerSelect(c, x, y, result ssa.Value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *machine) lowerSelectVec(rc, rn, rm, rd operand) {
|
func (m *machine) lowerSelectVec(rc, rn, rm, rd operand) {
|
||||||
tmp := operandNR(m.compiler.AllocateVReg(ssa.TypeI64))
|
// Declare and insert the conditional branch here jump to label `ifNonZero` below:
|
||||||
|
// but we cannot forward reference the label.
|
||||||
|
cbr := m.allocateInstr()
|
||||||
|
m.insert(cbr)
|
||||||
|
|
||||||
// Sets all bits to 1 if rc is not zero.
|
// If rc is zero, mov rd, rm then jump to end.
|
||||||
alu := m.allocateInstr()
|
mov0 := m.allocateInstr()
|
||||||
alu.asALU(aluOpSub, tmp, operandNR(xzrVReg), rc, true)
|
mov0.asFpuMov128(rd.nr(), rm.nr())
|
||||||
m.insert(alu)
|
m.insert(mov0)
|
||||||
|
|
||||||
// Then move the bits to the result vector register.
|
// Declared and insert the non-conditional jump to label `end` below:
|
||||||
dup := m.allocateInstr()
|
// again, we cannot forward reference the label.
|
||||||
dup.asVecDup(rd, tmp, vecArrangement2D)
|
br := m.allocateInstr()
|
||||||
m.insert(dup)
|
m.insert(br)
|
||||||
|
|
||||||
// Now that `rd` has either all bits one or zero depending on `rc`,
|
// Create and insert the label, and update `cbr` to the real instruction.
|
||||||
// we can use bsl to select between `rn` and `rm`.
|
ifNonZero := m.insertBrTargetLabel()
|
||||||
ins := m.allocateInstr()
|
cbr.asCondBr(registerAsRegNotZeroCond(rc.nr()), ifNonZero, true)
|
||||||
ins.asVecRRR(vecOpBsl, rd, rn, rm, vecArrangement16B)
|
|
||||||
m.insert(ins)
|
// If rc is non-zero, set mov rd, rn.
|
||||||
|
mov := m.allocateInstr()
|
||||||
|
mov.asFpuMov128(rd.nr(), rn.nr())
|
||||||
|
m.insert(mov)
|
||||||
|
|
||||||
|
// Create and insert the label, and update `br` to the real instruction.
|
||||||
|
end := m.insertBrTargetLabel()
|
||||||
|
br.asBr(end)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -842,9 +842,12 @@ func TestMachine_lowerSelectVec(t *testing.T) {
|
|||||||
|
|
||||||
m.lowerSelectVec(c, rn, rm, rd)
|
m.lowerSelectVec(c, rn, rm, rd)
|
||||||
require.Equal(t, `
|
require.Equal(t, `
|
||||||
sub x5?, xzr, x1?
|
cbnz x1?, L1
|
||||||
dup v4?.2d, x5?
|
mov v4?.16b, v3?.16b
|
||||||
bsl v4?.16b, v2?.16b, v3?.16b
|
b L2
|
||||||
|
L1:
|
||||||
|
mov v4?.16b, v2?.16b
|
||||||
|
L2:
|
||||||
`, "\n"+formatEmittedInstructionsInCurrentBlock(m)+"\n")
|
`, "\n"+formatEmittedInstructionsInCurrentBlock(m)+"\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ func Test696(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{fnName: "select", in: 1, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}},
|
{fnName: "select", in: 1, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}},
|
||||||
{fnName: "select", in: 0, exp: [2]uint64{0x1111111111111111, 0x2222222222222222}},
|
{fnName: "select", in: 0, exp: [2]uint64{0x1111111111111111, 0x2222222222222222}},
|
||||||
|
{fnName: "select", in: 0xffffff, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}},
|
||||||
|
{fnName: "select", in: 0x000000, exp: [2]uint64{0x1111111111111111, 0x2222222222222222}},
|
||||||
{fnName: "typed select", in: 1, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}},
|
{fnName: "typed select", in: 1, exp: [2]uint64{0xffffffffffffffff, 0xeeeeeeeeeeeeeeee}},
|
||||||
{fnName: "typed select", in: 0, exp: [2]uint64{0x1111111111111111, 0x2222222222222222}},
|
{fnName: "typed select", in: 0, exp: [2]uint64{0x1111111111111111, 0x2222222222222222}},
|
||||||
} {
|
} {
|
||||||
|
|||||||
Reference in New Issue
Block a user