Closed Quuxplusone closed 16 years ago
Bugzilla Link | PR2529 |
Status | RESOLVED FIXED |
Importance | P normal |
Reported by | Stefanus Du Toit (sdt@rapidmind.com) |
Reported on | 2008-07-07 16:51:08 -0700 |
Last modified on | 2008-07-10 10:51:18 -0700 |
Version | trunk |
Hardware | PC All |
CC | llvm-bugs@lists.llvm.org |
Fixed by commit(s) | |
Attachments | |
Blocks | |
Blocked by | |
See also |
Fixed, thanks!
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20080707/064662.html
Thanks for the speedy fix. This fixed vicmp, but vfcmp still fails for me
(r53241):
define <4 x i32> @test(i32 %argc, i8** %argv) {
entry:
%foo = vfcmp ueq <4 x float> <float undef, float undef, float undef, float
undef>, <float undef, float undef, float undef, float undef>
ret <4 x i32> %foo
}
opt -instcombine crashes in the same spot.
Looking into this a little it appears the patch doesn't actually fix vector
comparisons with undef to return undef. In fact, in the vicmp slt case, the
instructions is folded into a vector of zeroes!
One problem is this:
if (isa<UndefValue>(C1) || isa<UndefValue>(C2)) {
A vector of undefs is not an instance of UndefValue (apparently), so this
condition is false. In the case of a vicmp, this falls into the
"evaluateICmpRelation" path which apparently decides that the undef operands
are equal (should it really?).
In the case of vfcmp, it fails elsewhere.
First off, this piece of code is suspicious (ConstantFold.cpp:1353):
if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ) {
for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) {
Constant *C = ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ,
CP1->getOperand(i),
CP2->getOperand(i));
if (ConstantInt *CB = dyn_cast<ConstantInt>(C))
return CB;
}
This is in an if statement that has already determined that C1/C2 are vectors.
This will return an i1 if two corresponding components in the vectors are
constants (not undefs!). Clearly that's just completely wrong.
I confirmed this by trying:
%foo = vfcmp ueq <4 x float> <float 0.0, float 0.0, float 0.0, float undef>,
<float 1.0, float 1.0, float 1.0, float undef>
Which leads to the replaceAllUses assertion.
I also happened to notice that using entirely constant values crashes
instcombine somewhere else:
%foo = vfcmp ueq <4 x float> <float 0.0, float 0.0, float 0.0, float 0.0>,
<float 1.0, float 1.0, float 1.0, float 1.0>
causes infinite recursion with this in the backtrace:
#3792 0x0869548a in llvm::ConstantFoldCompareInstruction (pred=32,
C1=0x87d4d58, C2=0x87d6c98) at ConstantFold.cpp:1445
#3793 0x08609a96 in llvm::ConstantExpr::getICmp (pred=32, LHS=0x87d4d58,
RHS=0x87d6c98) at Constants.cpp:2134
#3794 0x086938c4 in evaluateICmpRelation (V1=0x87d4d58, V2=0x87d6c98,
isSigned=false) at ConstantFold.cpp:1035
Returning back to the vfcmp undef case, this case doesn't return a constant
from ConstantFoldCompareInstruction, but instead continues on in getFCmp, where
it reaches this point:
return ExprConstants->getOrCreate(Type::Int1Ty, Key);
which of course will create an i1. In fact, it returns this:
i1 fcmp ueq (<4 x float> < float undef, float undef, float undef, float undef >, <4 x float> < float undef, float undef, float undef, float undef >)
Obviously that's not right :)
I've fixed the issues you identified. If you hit more cases, please open a new
bug and include testcases, rather than reopening this one. Thanks,
-Chris
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20080707/064837.html
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20080707/064840.html
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20080707/064841.html
Thanks Chris! Will do.