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) {
|
||||
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.
|
||||
alu := m.allocateInstr()
|
||||
alu.asALU(aluOpSub, tmp, operandNR(xzrVReg), rc, true)
|
||||
m.insert(alu)
|
||||
// If rc is zero, mov rd, rm then jump to end.
|
||||
mov0 := m.allocateInstr()
|
||||
mov0.asFpuMov128(rd.nr(), rm.nr())
|
||||
m.insert(mov0)
|
||||
|
||||
// Then move the bits to the result vector register.
|
||||
dup := m.allocateInstr()
|
||||
dup.asVecDup(rd, tmp, vecArrangement2D)
|
||||
m.insert(dup)
|
||||
// Declared and insert the non-conditional jump to label `end` below:
|
||||
// again, we cannot forward reference the label.
|
||||
br := m.allocateInstr()
|
||||
m.insert(br)
|
||||
|
||||
// Now that `rd` has either all bits one or zero depending on `rc`,
|
||||
// we can use bsl to select between `rn` and `rm`.
|
||||
ins := m.allocateInstr()
|
||||
ins.asVecRRR(vecOpBsl, rd, rn, rm, vecArrangement16B)
|
||||
m.insert(ins)
|
||||
// Create and insert the label, and update `cbr` to the real instruction.
|
||||
ifNonZero := m.insertBrTargetLabel()
|
||||
cbr.asCondBr(registerAsRegNotZeroCond(rc.nr()), ifNonZero, true)
|
||||
|
||||
// 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)
|
||||
require.Equal(t, `
|
||||
sub x5?, xzr, x1?
|
||||
dup v4?.2d, x5?
|
||||
bsl v4?.16b, v2?.16b, v3?.16b
|
||||
cbnz x1?, L1
|
||||
mov v4?.16b, v3?.16b
|
||||
b L2
|
||||
L1:
|
||||
mov v4?.16b, v2?.16b
|
||||
L2:
|
||||
`, "\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: 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: 0, exp: [2]uint64{0x1111111111111111, 0x2222222222222222}},
|
||||
} {
|
||||
|
||||
Reference in New Issue
Block a user