Preferring cast over seteq with 0

Is there a pass that will transform this:
  %cc = seteq ushort %val, 0

into this:
  %cc = cast ushort %val to bool

Would instcombine be the logical place to do this?

In my situation, this bool value feeds a select instruction. Because
casting inverts the condition, the select would have to switch the
operands, but I think it would be beneficial.

I think that the instcombine pass should take care of this situation. Do
you have a simple testcase that shows the problem?

-Chris

Hi Chris,
  I am targeting the alpha platform. I pasted a portion of the
problem code below. I starred a select in the join block that is fed
by the seteq (%tmp.37) in the entry block. The resultant alpha code
places an unnecessary cmpeq in block 'entry'. When I move the
definition of %tmp.37 to block 'join', the Alpha backend correctly
eliminates the cmpeq.

I think rather than changing the cast/seteq behavior, I can get the
same results for alpha by moving the seteq to the block where it is
used.

-Eric

implementation ; Functions:

int %FirstOne(ulong %arg1) {
entry:
        %x = alloca ulong ; <ulong*> [#uses=2]
        store ulong %arg1, ulong* %x
        %tmp.3 = cast ulong* %x to [4 x ushort]* ; <[4 x ushort]*> [#uses=2]
        %tmp.35 = getelementptr [4 x ushort]* %tmp.3, int 0, int 1 ; <ushort*> [#uses=1]
        %tmp.36 = load ushort* %tmp.35 ; <ushort> [#uses=1]
*** %tmp.37 = seteq ushort %tmp.36, 0 ; <bool> [#uses=1]
        %tmp.51 = getelementptr [4 x ushort]* %tmp.3, int 0, int 0 ; <ushort*> [#uses=1]
        %tmp.52 = load ushort* %tmp.51 ; <ushort> [#uses=2]
        %tmp.53 = seteq ushort %tmp.52, 0 ; <bool> [#uses=1]
        br bool %tmp.53, label %join, label %then.3

then.3: ; preds = %entry
        %tmp.59 = cast ushort %tmp.52 to int ; <int> [#uses=1]
        %tmp.64 = add int %tmp.59, 48 ; <int> [#uses=1]
        br label %join

join: ; preds = %then.3, %entry
        %joinPHI = phi int [ %tmp.64, %then.3 ], [ 64, %entry ] ; <int> [#uses=1]
*** %joinPHI.tmp.48 = select bool %tmp.37, int %joinPHI, int 42 ; <int> [#uses=1]
        ret int %joinPHI.tmp.48
}

In my situation, this bool value feeds a select instruction. Because
casting inverts the condition, the select would have to switch the
operands, but I think it would be beneficial.

I think that the instcombine pass should take care of this situation. Do
you have a simple testcase that shows the problem?

Hi Chris,
I am targeting the alpha platform. I pasted a portion of the
problem code below. I starred a select in the join block that is fed
by the seteq (%tmp.37) in the entry block. The resultant alpha code
places an unnecessary cmpeq in block 'entry'. When I move the
definition of %tmp.37 to block 'join', the Alpha backend correctly
eliminates the cmpeq.

I don't think that this is due to a cast vs setcc issue. In theory they should both generate identical code.

I think rather than changing the cast/seteq behavior, I can get the
same results for alpha by moving the seteq to the block where it is
used.

Yup, I think this is the real issue. It should be straight-forward to make the inst combine pass sink setcc to the select instruction. If you're interested in tackling this, you want to add something like this to visitSelectInst:

   if (SetCondInst *SCI = dyn_cast<SetCondInst>(CondVal))
     if (SCI->hasOneUse() && SCI->getParent() != SI.getParent()) {
       SI.getParent().getInstList().splice(&SI,
                       SCI->getParent()->getInstList(), SCI);
       return &SI;
     }

I'm sorry I can't take care of this myself, the computers here have decided to not cooperate.

-Chri

-Eric

implementation ; Functions:

int %FirstOne(ulong %arg1) {
entry:
       %x = alloca ulong ; <ulong*> [#uses=2]
       store ulong %arg1, ulong* %x
       %tmp.3 = cast ulong* %x to [4 x ushort]* ; <[4 x ushort]*> [#uses=2]
       %tmp.35 = getelementptr [4 x ushort]* %tmp.3, int 0, int 1 ; <ushort*> [#uses=1]
       %tmp.36 = load ushort* %tmp.35 ; <ushort> [#uses=1]
*** %tmp.37 = seteq ushort %tmp.36, 0 ; <bool> [#uses=1]
       %tmp.51 = getelementptr [4 x ushort]* %tmp.3, int 0, int 0 ; <ushort*> [#uses=1]
       %tmp.52 = load ushort* %tmp.51 ; <ushort> [#uses=2]
       %tmp.53 = seteq ushort %tmp.52, 0 ; <bool> [#uses=1]
       br bool %tmp.53, label %join, label %then.3

then.3: ; preds = %entry
       %tmp.59 = cast ushort %tmp.52 to int ; <int> [#uses=1]
       %tmp.64 = add int %tmp.59, 48 ; <int> [#uses=1]
       br label %join

join: ; preds = %then.3, %entry
       %joinPHI = phi int [ %tmp.64, %then.3 ], [ 64, %entry ] ; <int> [#uses=1]
*** %joinPHI.tmp.48 = select bool %tmp.37, int %joinPHI, int 42 ; <int> [#uses=1]
       ret int %joinPHI.tmp.48
}

_______________________________________________
LLVM Developers mailing list
LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev

-Chris