32 bit boolean results

Is there a way to tell LLVM to treat Boolean results as 32bit values
instead of 1 bit values?

Thanks,

Micah Villmow

Systems Engineer

Advanced Technology & Performance

Advanced Micro Devices Inc.

4555 Great America Pkwy,

Santa Clara, CA. 95054

P: 408-572-6219

F: 408-572-6596

LLVM IR doesn’t have a concept of C level booleans. What problem are you trying to solve?

-Chris

I am still trying to figure out why my comparison instructions are being
modified and overall producing incorrect results.

The IR produces correct results, but my backend does not and the only
thing I can think of is that the IR is treating the Booleans as i1 and
therefore either and'ing or xor'ing the results of my comparison with
the value 1.

Sorry, accidently hit send hotkeys before finishing email.

I am still trying to figure out why my comparison instructions are being
modified and overall producing incorrect results.

The IR produces correct results, but my backend does not and the only
thing I can think of is that the IR is treating the Booleans as i1 and
therefore either and'ing or xor'ing the results of my comparison with
the value 1.

This is causing the IR after running opt to be correct, but when it hits
my backend, there are some changes that generate something weird.

int gID = width;

const int idx = gID % 64;

const int idy = gID / 64;

pv[gID] = 0;

if( idy > 63 && idx > 0 )

{

            pv[gID]=1;

}

generates conditionals :

            ult r1043.x, 63, r1026.x

            ilt r1041.x, r1039.x, 1

            and r1041.x, r1041.x, r1043.x

            if_logicalz r1041.x

             //write to pv

            endif

which is C for

if ((63 < idy && idx < 1) == 0) {

}

I have no clue how the 1 gets put in there but being able to stop the
xor/and instructions from being inserted and modifying my comparison
instructions would help me pinpoint where the error is.

Micah

The IR produces correct results, but my backend does not and the only thing
I can think of is that the IR is treating the Booleans as i1 and therefore
either and'ing or xor'ing the results of my comparison with the value 1.

CodeGen assumes that SETCC(true condition) & 1 == 1, and SETCC(false
condition) & 1 == 0. For details, look in SelectionDAGNodes.h. If
your comparisons are returning something unusual, you may have to
custom-lower them.

I have no clue how the 1 gets put in there

(!(idx > 0)) == (idx <= 0) == (idx < 1). Most likely the DAGCombiner
is doing this.

What should be happening is something like the following:
Branch lowering transforms the code into something like the following
to save a jump:
if (!(idy > 63 && idx > 0)) goto afterif;
<code in if>
afterif:
<code after if>

Then, !(idy > 63 && idx > 0) gets combined to (idy < 64 || idx < 1).

Then, your legalization transforms the branch condition into (!(idy <
64 || idx < 1) == 0).

Then, combine reorganizes this back into (idy > 63 && idx > 0).

It's hard to say where this is messing up.

-Eli

You can tell LLVM that you have "sign extended" setCC results (all ones).

Dan

Dan/Eli,
The problem doesn't seem to be the results of setCC, but in the actual
arguments being passed in to my lowered setCC/br_CC function
For example, when I have code that does
if (x < 1) { do1 } else { do2 }
SetCC/BR_CC get passed in
Op0: TokenFactor
Op1: setgt
Op2: CopyFromReg:Reg1027:x
Op3: Constant:0
Op4: IfElseBB
or in C
if (x > 0) { do2 } else { do1 }

if (x > 0) always turns into if (x > 1)
if (x < 0) always turns into if (x < -1)
if (x > 0.0f) turns into if (x <= 0.0f)
if (x < 0.0f) turns into if (x >= 0.0f)

... This is all happening before it gets to my custom lowered functions.

If I do -view-dag-combine1-dags, then the correct constant value is
used.
However when it hits my LowerBR_CC function the incorrect constant is
used and when I do -view-dag-combine2-dags or -view-legalize-dags the
incorrect constant value also appears.

I'm pretty sure it is not my backend, since the constants are incorrect
before I touch them. So, where should I be looking to figure out what is
wrong?

Thanks,

This is how I am matching constants:
multiclass ILConstant<string asm> {
    def _i32 : ILFormat<(outs GPRI32:$dst), (ins i32imm:$val),
        asm, [(set GPRI32:$dst, imm:$val)]>;
    def _f32 : ILFormat<(outs GPRF32:$dst), (ins f32imm:$val),
        asm, [(set (f32 GPRF32:$dst), fpimm:$val)]>;
    def _i64 : ILFormat<(outs GPRI64:$dst), (ins i64imm:$val),
        asm, [(set (i64 GPRI64:$dst), imm:$val)]>;
    def _f64 : ILFormat<(outs GPRF64:$dst), (ins f64imm:$val),
        asm, [(set (f64 GPRF64:$dst), fpimm:$val)]>;
}

This is my LowerBR_CC:
SDValue AMDilTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG& DAG){
    MVT VT = Op.getValueType();
    SDValue Chain = Op.getOperand(0);
    SDValue LHS = Op.getOperand(2);
    SDValue RHS = Op.getOperand(3);
    SDValue Jump = Op.getOperand(4);
    SDValue CmpValue;
    ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
    SDValue Result;
    unsigned int cmpOpcode = CondCCodeToCC(CC,
LHS.getValueType().getSimpleVT());
    CmpValue = DAG.getNode(AMDILISD::CMP, LHS.getValueType(),
DAG.getConstant(cmpOpcode, MVT::i32), LHS, RHS);
    Result = DAG.getNode(AMDILISD::BRANCH_COND, MVT::Other, Chain, Jump,
CmpValue);
    return Result;
}