ConstantFolding: Add a missing folding that leads to a miscompile.

We use constant folding to see if an intrinsic evaluates to the same value as a
constant that we know. If we don't take the undefinedness into account we get a
value that doesn't match the actual implementation, and miscompiled code.

This was uncovered by Chandler's simplifycfg changes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173356 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer
2013-01-24 16:28:28 +00:00
parent 41d35a335e
commit e574246489
3 changed files with 41 additions and 5 deletions

View File

@ -1474,12 +1474,12 @@ llvm::ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
return ConstantStruct::get(cast<StructType>(F->getReturnType()), Ops);
}
case Intrinsic::cttz:
// FIXME: This should check for Op2 == 1, and become unreachable if
// Op1 == 0.
if (Op2->isOne() && Op1->isZero()) // cttz(0, 1) is undef.
return UndefValue::get(Ty);
return ConstantInt::get(Ty, Op1->getValue().countTrailingZeros());
case Intrinsic::ctlz:
// FIXME: This should check for Op2 == 1, and become unreachable if
// Op1 == 0.
if (Op2->isOne() && Op1->isZero()) // ctlz(0, 1) is undef.
return UndefValue::get(Ty);
return ConstantInt::get(Ty, Op1->getValue().countLeadingZeros());
}
}