Skip to content

[InstCombine] Wrong negation of vector selection with a poison value #114181

Closed
@bongjunj

Description

@bongjunj

case Instruction::Select: {
if (isKnownNegation(I->getOperand(1), I->getOperand(2), /*NeedNSW=*/false,
/*AllowPoison=*/false)) {
// Of one hand of select is known to be negation of another hand,
// just swap the hands around.
auto *NewSelect = cast<SelectInst>(I->clone());
// Just swap the operands of the select.
NewSelect->swapValues();
// Don't swap prof metadata, we didn't change the branch behavior.
NewSelect->setName(I->getName() + ".neg");
Builder.Insert(NewSelect);
return NewSelect;
}
// `select` is negatible if both hands of `select` are negatible.
Value *NegOp1 = negate(I->getOperand(1), IsNSW, Depth + 1);
if (!NegOp1) // Early return.
return nullptr;
Value *NegOp2 = negate(I->getOperand(2), IsNSW, Depth + 1);
if (!NegOp2)
return nullptr;
// Do preserve the metadata!
return Builder.CreateSelect(I->getOperand(0), NegOp1, NegOp2,
I->getName() + ".neg", /*MDFrom=*/I);
}

Alive2 report: https://alive2.llvm.org/ce/z/tdHHuq

----------------------------------------
define <2 x i32> @negate_select_of_negation_poison.2(<2 x i1> %c, <2 x i32> %x) {
#0:
  %#1 = srem <2 x i32> { poison, 0 }, %x
  %neg = sub nsw <2 x i32> %#1, %x
  %sel = select <2 x i1> %c, <2 x i32> %neg, <2 x i32> %x
  %neg2 = sub <2 x i32> %x, %sel
  ret <2 x i32> %neg2
}
=>
define <2 x i32> @negate_select_of_negation_poison.2(<2 x i1> %c, <2 x i32> %x) {
#0:
  %neg = sub nsw <2 x i32> { 0, 0 }, %x
  %#1 = select <2 x i1> %c, <2 x i32> %x, <2 x i32> %neg
  %neg2 = add <2 x i32> %#1, %x
  ret <2 x i32> %neg2
}
Transformation doesn't verify!

ERROR: Target is more poisonous than source

Example:
<2 x i1> %c = < #x0 (0), #x0 (0) >
<2 x i32> %x = < #x80000000 (2147483648, -2147483648), #x0000000d (13) >

Source:
<2 x i32> %#1 = < poison, #x00000000 (0) >
<2 x i32> %neg = < poison, #xfffffff3 (4294967283, -13) >
<2 x i32> %sel = < #x80000000 (2147483648, -2147483648), #x0000000d (13) >
<2 x i32> %neg2 = < #x00000000 (0), #x00000000 (0) >

Target:
<2 x i32> %neg = < poison, #xfffffff3 (4294967283, -13) >
<2 x i32> %#1 = < poison, #xfffffff3 (4294967283, -13) >
<2 x i32> %neg2 = < poison, #x00000000 (0) >
Source value: < #x00000000 (0), #x00000000 (0) >
Target value: < poison, #x00000000 (0) >

Summary:
  0 correct transformations
  1 incorrect transformations
  0 failed-to-prove transformations
  0 Alive2 errors

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions