troubles with ISD::FPOWI

Hi,

I'm stumped by how to handle fpowi. Here is the context: my architecture has i64, f32, and f64 registers. No i32. For calls & returns, we promote i32 to i64. There is no support in the architecture to perform fpowi - it has to go through the runtime.

I'm using gfortran + dragonegg + llvm3.4 to generate .ll files via plugin.
The fortran expression
  REAL = REAL ** INTEGER*4
Resulting in:
  %4 = call float @llvm.powi.f32(float %1, i32 %3)

So far, not unreasonable.
But when I run this through the compiler, it asserts:

-bash-4.1$ $DEVCLANG -target coge -O -S slamchf77.ll -mllvm -debug
...
Promote integer result: 0x56061c0: i32 = sub 0x56049a0, 0x56046a0 [ORD=161] [ID=0]

Promote integer operand: 0x56059c0: f32 = fpowi 0x5602580, 0x56061c0 [ORD=162] [ID=0]

PromoteIntegerOperand Op #1: 0x56059c0: f32 = fpowi 0x5602580, 0x56061c0 [ORD=162] [ID=0]

Do not know how to promote this operator's operand!

Hi Richard,

Hi,

I'm stumped by how to handle fpowi. Here is the context: my architecture has i64, f32, and f64 registers. No i32. For calls & returns, we promote i32 to i64. There is no support in the architecture to perform fpowi - it has to go through the runtime.

I'm using gfortran + dragonegg + llvm3.4 to generate .ll files via plugin.
The fortran expression
  REAL = REAL ** INTEGER*4
Resulting in:
   %4 = call float @llvm.powi.f32(float %1, i32 %3)

So far, not unreasonable.
But when I run this through the compiler, it asserts:

-bash-4.1$ $DEVCLANG -target coge -O -S slamchf77.ll -mllvm -debug
...
Promote integer result: 0x56061c0: i32 = sub 0x56049a0, 0x56046a0 [ORD=161] [ID=0]

Promote integer operand: 0x56059c0: f32 = fpowi 0x5602580, 0x56061c0 [ORD=162] [ID=0]

PromoteIntegerOperand Op #1: 0x56059c0: f32 = fpowi 0x5602580, 0x56061c0 [ORD=162] [ID=0]

Do not know how to promote this operator's operand!

you probably want to do the following: add a method for FPOWI in PromoteIntegerResult. In the method, get the i64 version of the second operand using:
     SDValue Op = SExtPromotedInteger(N->getOperand(1));
Create and return a new FPOWI node that is the same as the original, only it uses Op as the second operand.

Ciao, Duncan.

I'm missing something - I tried that, and also adding some code to PromoteIntegerOperand to do that, but get other errors.
I submitted bug 21042 (with the .ll file as an example)

Hi Richard,

I'm missing something - I tried that, and also adding some code to PromoteIntegerOperand to do that, but get other errors.

using SExtPromotedInteger as I suggested is more efficient than using SIGN_EXTEND[_INREG], but indeed the result will be the same.

I submitted bug 21042 (with the .ll file as an example)

Please also attach the patch(es) you tried and the assertions you hit.

Ciao, Duncan.