[llvm-bugs] [Bug 51242] New: Global Isel Fail on ZExt

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Jul 28 01:57:39 PDT 2021


https://bugs.llvm.org/show_bug.cgi?id=51242

            Bug ID: 51242
           Summary: Global Isel Fail on ZExt
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: GlobalISel
          Assignee: unassignedbugs at nondot.org
          Reporter: guopeilin1 at huawei.com
                CC: llvm-bugs at lists.llvm.org, quentin.colombet at gmail.com

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

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210728/79115519/attachment-0001.html>


More information about the llvm-bugs mailing list