"Cannot select" error in 2.9

Hi all

I didn't find anything relevant in the archives about this so I wanted to
ask here.

I am generating a simple function for JIT using the API. The function
structure and code work fine with 2.8 but give me "Cannot select" with 2.9.

Assembly dump of the function:

define double @0(double %f0, double %f1, double %f2, double %f3, double %f4,
double %f5, double %f6, double %f7, double %f8, double %f9) {
  %1 = add double %f0, %f1
  %2 = add double %1, %f2
  %3 = add double %2, %f3
  %4 = add double %3, %f4
  %5 = add double %4, %f5
  %6 = add double %5, %f6
  %7 = add double %6, %f7
  %8 = add double %7, %f8
  %9 = add double %8, %f9
  ret double %9
}

LLVM error I get:

LLVM ERROR: Cannot select: 0xd1b720: f64 = add 0xd1b620, 0xd1ae20 [ORD=9]
[ID=32]
  0xd1b620: f64 = add 0xd1b520, 0xd1ac20 [ORD=8] [ID=31]
    0xd1b520: f64 = add 0xd1b420, 0xd1a920 [ORD=7] [ID=30]
      0xd1b420: f64 = add 0xd1b320, 0xd1a610 [ORD=6] [ID=29]
        0xd1b320: f64 = add 0xd1b220, 0xd1a410 [ORD=5] [ID=28]
          0xd1b220: f64 = add 0xd1b120, 0xd1a210 [ORD=4] [ID=27]
            0xd1b120: f64 = add 0xd1b020, 0xd1a010 [ORD=3] [ID=26]
              0xd1b020: f64 = add 0xd1af20, 0xd19e10 [ORD=2] [ID=25]
                0xd1af20: f64 = add 0xd19a10, 0xd19c10 [ORD=1] [ID=24]
                  0xd19a10: f64,ch = CopyFromReg 0xcee028, 0xd19910 [ORD=1]
[ID=14]

                  0xd19c10: f64,ch = CopyFromReg 0xcee028, 0xd19b10 [ORD=1]
[ID=15]

                0xd19e10: f64,ch = CopyFromReg 0xcee028, 0xd19d10 [ORD=2]
[ID=16]
                  0xd19d10: f64 = Register %vreg2 [ORD=2] [ID=3]
              0xd1a010: f64,ch = CopyFromReg 0xcee028, 0xd19f10 [ORD=3]
[ID=17]
                0xd19f10: f64 = Register %vreg3 [ORD=3] [ID=4]
            0xd1a210: f64,ch = CopyFromReg 0xcee028, 0xd1a110 [ORD=4]
[ID=18]
              0xd1a110: f64 = Register %vreg4 [ORD=4] [ID=5]
          0xd1a410: f64,ch = CopyFromReg 0xcee028, 0xd1a310 [ORD=5] [ID=19]
            0xd1a310: f64 = Register %vreg5 [ORD=5] [ID=6]
        0xd1a610: f64,ch = CopyFromReg 0xcee028, 0xd1a510 [ORD=6] [ID=20]
          0xd1a510: f64 = Register %vreg6 [ORD=6] [ID=7]
      0xd1a920: f64,ch = CopyFromReg 0xcee028, 0xd1a710 [ORD=7] [ID=21]
        0xd1a710: f64 = Register %vreg7 [ORD=7] [ID=8]
    0xd1ac20: f64,ch = load 0xcee028, 0xd1aa20,
0xd1ab20<LD8[FixedStack-1](align=16)> [ORD=8] [ID=22]
      0xd1aa20: i64 = FrameIndex<-1> [ORD=8] [ID=9]
      0xd1ab20: i64 = undef [ORD=8] [ID=10]
  0xd1ae20: f64,ch = load 0xcee028, 0xd1ad20, 0xd1ab20<LD8[FixedStack-2]>
[ORD=9] [ID=23]
    0xd1ad20: i64 = FrameIndex<-2> [ORD=9] [ID=11]
    0xd1ab20: i64 = undef [ORD=8] [ID=10]

Is there something different I need to do in my function definition or
structure to get by this? Or is this a bug?

Thanks
Greg

Hi Gregory,

I didn't find anything relevant in the archives about this so I wanted to
ask here.

I am generating a simple function for JIT using the API. The function
structure and code work fine with 2.8 but give me "Cannot select" with 2.9.

did you initialize the target?

Ciao, Duncan.

Yes, InitializeNativeTarget() is the first thing called.

Greg

Hi Nadav

I'm not sure what those are -- can you clarify?

Thanks
Greg

OK bugpoint was simple enough to figure out -- it tells me

bugpoint: test.ll:2:12: error: invalid operand type for instruction

  %1 = add double %f0, %f1

That doesn't make a lot of sense to me -- LLVM can't add doubles? For
completeness, the original assembly dump:

define double @0(double %f0, double %f1, double %f2, double %f3, double %f4,
double %f5, double %f6, double %f7, double %f8, double %f9) {
  %1 = add double %f0, %f1
  %2 = add double %1, %f2
  %3 = add double %2, %f3
  %4 = add double %3, %f4
  %5 = add double %4, %f5
  %6 = add double %5, %f6
  %7 = add double %6, %f7
  %8 = add double %7, %f8
  %9 = add double %8, %f9
  ret double %9
}

Thanks
Greg

Gregory Junker wrote:

From: Rotem, Nadav [mailto:nadav.rotem@intel.com]
Sent: Saturday, July 30, 2011 6:51 AM
To: Gregory Junker
Subject: RE: [LLVMdev] "Cannot select" error in 2.9

Can you reduce the test with bug-point ? Does it work on ToT ?

Hi Nadav

I'm not sure what those are -- can you clarify?

OK bugpoint was simple enough to figure out -- it tells me

bugpoint: test.ll:2:12: error: invalid operand type for instruction

   %1 = add double %f0, %f1

That doesn't make a lot of sense to me -- LLVM can't add doubles?

No, LLVM can't, but it can fadd them. :wink: "add" only accepts integers and vectors of integers, "fadd" accepts floats and vectors of floats. See their entries in the language reference:

   add: LLVM Language Reference Manual — LLVM 18.0.0git documentation
   fadd: LLVM Language Reference Manual — LLVM 18.0.0git documentation

The split is intended to let us add additional properties to integer adds (like the nuw/nsw bits documented) that don't apply to floats, and properties to floats (rounding modes) that don't apply to ints.

Nick

  For

Ah interesting -- this was introduced in 2.9 then? Easy enough for me to fix
this in my code.

Out of curiosity, was this documented anywhere? I ask because I looked
through release notes and either missed this or didn't see it, and I'd like
to find out what else changed so I can make the necessary adjustments in my
code.

Thanks!
Greg

Yup, that sorted it for me -- thanks Nick and Nadav for pointing me in the
right direction!

Greg

From: Nick Lewycky [mailto:nicholas@mxc.ca]

[snip]

Gregory Junker wrote:
> That doesn't make a lot of sense to me -- LLVM can't add doubles?

No, LLVM can't, but it can fadd them. :wink: "add" only accepts integers
and
vectors of integers, "fadd" accepts floats and vectors of floats. See
their entries in the language reference:

[snip]

Ah interesting -- this was introduced in 2.9 then? Easy enough for me to fix
this in my code.

Out of curiosity, was this documented anywhere? I ask because I looked
through release notes and either missed this or didn't see it, and I'd like
to find out what else changed so I can make the necessary adjustments in my
code.

Actually, it was new in *2.6*, which was released almost two years
ago. It's documented here:
<LLVM 2.6 Release Notes.

Actually, it was new in *2.6*, which was released almost two years
ago. It's documented here:
<http://llvm.org/releases/2.6/docs/ReleaseNotes.html#coreimprovements&gt;\.

Interesting -- then I guess my question is why 2.8 (which is the first version of LLVM I've used) didn't flag this?

Either way, it makes sense and changing my API usage to call CreateFAdd instead of CreateAdd fixes this.

Thanks
Greg

Gregory Junker wrote:

Actually, it was new in *2.6*, which was released almost two years
ago. It's documented here:
<LLVM 2.6 Release Notes.

Interesting -- then I guess my question is why 2.8 (which is the first version of LLVM I've used) didn't flag this?

Either way, it makes sense and changing my API usage to call CreateFAdd instead of CreateAdd fixes this.

For a while, we kept some API backwards compatibility magic in place which would forward creations of adds into creations of fadds.

Nick

Figured it might be something like that. :wink:

Thanks again!
Greg

Either way, it makes sense and changing my API usage to call

CreateFAdd instead of CreateAdd fixes this.

Shouldn't the verifier have caught this?

Ciao, Duncan.