<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - Global Isel Fail on ZExt"
href="https://bugs.llvm.org/show_bug.cgi?id=51242">51242</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Global Isel Fail on ZExt
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>GlobalISel
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>guopeilin1@huawei.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org, quentin.colombet@gmail.com
</td>
</tr></table>
<p>
<div>
<pre>using `llc -O2 test.ll`, global isel faila on the following example:
```
@b = dso_local global [2 x i32] [i32 0, i32 1], align 4
@a = dso_local global i32 0, align 4
define dso_local i32 @main() {
entry:
ret i32 zext (i1 fcmp ogt (double 1.000000e+00, double uitofp (i1 icmp eq
(i32* getelementptr inbounds ([2 x i32], [2 x i32]* @b, i64 0, i64 1), i32* @a)
to double)) to i32)
}
```
The debug info is like the following:
`llvm-project/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp:345: bool
llvm::IRTranslator::translateCompare(const llvm::User&,
llvm::MachineIRBuilder&): Assertion `CI && "Instruction should be CmpInst"'
failed.`
The reason seems to be like the following:
The IRTranslator treats ZExt't operand as a const. However, if the ZExt's
operand is complicated such as the following example:
ret i32 zext (i1 fcmp ogt (double 1.000000e+00, double uitofp (i1 icmp eq (i32*
getelementptr inbounds ([2 x i32], [2 x i32]* @b, i64 0, i64 1), i32* @a) to
double)) to i32)
The FCMP within the ZExt is treated as a ConstExpr, however, we cannot get the
result directly, that is the function `getPredicate` is `
llvm::CmpInst::FCMP_OGT` rather than `True or False`. As a result, the FCMP is
not a CmpInst nor True/False, so finally get stuck in the assert shown in the
following code.
```
bool IRTranslator::translateCompare(const User &U,
MachineIRBuilder &MIRBuilder) {
auto *CI = dyn_cast<CmpInst>(&U);
Register Op0 = getOrCreateVReg(*U.getOperand(0));
Register Op1 = getOrCreateVReg(*U.getOperand(1));
Register Res = getOrCreateVReg(U);
CmpInst::Predicate Pred =
CI ? CI->getPredicate() : static_cast<CmpInst::Predicate>(
cast<ConstantExpr>(U).getPredicate());
if (CmpInst::isIntPredicate(Pred))
MIRBuilder.buildICmp(Pred, Res, Op0, Op1);
else if (Pred == CmpInst::FCMP_FALSE)
MIRBuilder.buildCopy(
Res, getOrCreateVReg(*Constant::getNullValue(U.getType())));
else if (Pred == CmpInst::FCMP_TRUE)
MIRBuilder.buildCopy(
Res, getOrCreateVReg(*Constant::getAllOnesValue(U.getType())));
else {
assert(CI && "Instruction should be CmpInst");
MIRBuilder.buildFCmp(Pred, Res, Op0, Op1,
MachineInstr::copyFlagsFromInstruction(*CI));
}
return true;
}
```
It seems that function `getOrCreateVRegs` needs take more cases into
consideration or the function `translateZExt` may need to be modified.
Any suggestions will be greatly appreciated</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>