Emit FCCMP for AND of two float compares

Hi Everyone! I was working on the issue: [AArch64] Missed FCCMP opportunity · Issue #60819 · llvm/llvm-project · GitHub . And I have created the patch for it: ⚙ D152714 [AArch64][Optimization]Emit FCCMP for AND of two float compares . But now I am unable to fix the test file i.e., select_fmf.ll. Can anyone please help me with that?

Looking at the generated code, it looks like what’s happening is that your new code is triggering on the testcase, but that blocks an existing transform that emits fccmp for a SELECT/SELECT_CC. You should be able to trace what’s happening with a debugger to be sure, but I expect the relevant code is getAArch64Cmp(). The code for lowering SELECT sees an AArch64ISD::CSINC, and doesn’t realize it can consume the flags directly.

I can think of a couple different ways to deal with this: one, you could walk the use list of the SETCC and see if it’s used by a SELECT. Or two, you could teach the SELECT lowering to look through the CSINC. The first is more conservative.

How can I see the use list of SETCC?

N->uses() returns the uses.

// Transform and(fcmp(a, b), fcmp(c, d)) into fccmp(fcmp(a, b), c, d)
static SDValue performANDSETCCCombine(SDNode *N,
                                      TargetLowering::DAGCombinerInfo &DCI) {

  // This function performs an optimization on a specific pattern involving
  // an AND operation and SETCC (Set Condition Code) node.

  SDValue SetCC = N->getOperand(0);
  EVT VT = N->getValueType(0);
  SelectionDAG &DAG = DCI.DAG;
  // Check if the operand is a SETCC node with floating-point comparison
  if (SetCC.getOpcode() == ISD::SETCC &&
      SetCC.getOperand(0).getValueType() == MVT::f32) {

    SDValue Cmp;
    AArch64CC::CondCode CC;

Like I use it like this then where the SETCC uses will be printed?

If I write it like this:


then it is giving me error.

Try something like for (auto U : N->uses()) U->dump();

Using this gives me the following error:

E:\llvm-project\llvm\lib\Target\AArch64\AArch64ISelLowering.cpp(16394,7): error C2146: syntax error: missing ')' before
 identifier 'U' [E:\llvm-build\lib\Target\AArch64\LLVMAArch64CodeGen.vcxproj]
E:\llvm-project\llvm\lib\Target\AArch64\AArch64ISelLowering.cpp(16394,7): error C2065: 'U': undeclared identifier [E:\l
E:\llvm-project\llvm\lib\Target\AArch64\AArch64ISelLowering.cpp(16394,7): error C3537: you cannot cast to a type that c
ontains 'auto' [E:\llvm-build\lib\Target\AArch64\LLVMAArch64CodeGen.vcxproj]
E:\llvm-project\llvm\lib\Target\AArch64\AArch64ISelLowering.cpp(16394,9): error C2143: syntax error: missing ';' before
 ':' [E:\llvm-build\lib\Target\AArch64\LLVMAArch64CodeGen.vcxproj]
E:\llvm-project\llvm\lib\Target\AArch64\AArch64ISelLowering.cpp(16394,9): error C2059: syntax error: ':' [E:\llvm-build
E:\llvm-project\llvm\lib\Target\AArch64\AArch64ISelLowering.cpp(16394,20): error C2059: syntax error: ')' [E:\llvm-buil

Did you omit the second close paren in uses( ) ) ?

No. Still it is giving error for ).

As far as I can tell, you didn’t actually use the code I wrote. Please actually use the code I wrote, as I wrote it.

For anyone else following along, the following generates a similar sequence of error messages

void f(void*N) {
    1<<(auto U : N->uses()) U->dump();

Okay! It worked. Thank you very much.