-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Closed
Labels
llvm:instcombineCovers the InstCombine, InstSimplify and AggressiveInstCombine passesCovers the InstCombine, InstSimplify and AggressiveInstCombine passesmiscompilation
Description
llvm-project/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
Lines 327 to 350 in 9a7519f
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
Labels
llvm:instcombineCovers the InstCombine, InstSimplify and AggressiveInstCombine passesCovers the InstCombine, InstSimplify and AggressiveInstCombine passesmiscompilation