[llvm-dev] Question about TargetLowering::SimplifyDemandedBits with AND

JinGu Kang via llvm-dev llvm-dev at lists.llvm.org
Tue Dec 22 05:01:05 PST 2015


Hi All,

I have faced a problem with TargetLowering::SimplifyDemandedBits with 
AND. Here is a example as following:

/* C source code */
struct A
{
   unsigned int a;
   unsigned char c1, c2;
   bool b1 : 1;
   bool b2 : 1;
   bool b3 : 1;
};

int main ()
{
   struct A x[1];
   x[0].b1 = false;

   int s = 0;
   s = x[0].b1 ? 1 : 0;   <--- Here is problem.

   if (s != 0)
     __builtin_abort ();
   return 0;
}

/* IR of "s = x[0].b1 ? 1 : 0;" */
...
   %b12 = getelementptr inbounds %struct.A, %struct.A* %arrayidx1, i32 
0, i32 3
   %bf.load3 = load i8, i8* %b12, align 2
   %bf.clear4 = and i8 %bf.load3, 1
   %bf.cast = trunc i8 %bf.clear4 to i1
   %cond = select i1 %bf.cast, i32 1, i32 0
   store i32 %cond, i32* %s, align 4
...

/* Initial Selection DAG of "s = x[0].b1 ? 1 : 0;" */
...
   0x81d17c0: i8,ch = load 0x81cca20, 0x81cbfb8, 
0x81cc0e0<LD1[%b12](align=2)> [ORD=14]

     0x81d17c0: <multiple use>
           0x81d17c0: <multiple use>
           0x81d18e8: i8 = Constant<1>

         0x81d1a10: i8 = and 0x81d17c0, 0x81d18e8 [ORD=15]

       0x81d1b38: i1 = truncate 0x81d1a10 [ORD=16]

       0x81d1c60: i32 = Constant<1>

       0x81cc330: <multiple use>
     0x81d1d88: i32 = select 0x81d1b38, 0x81d1c60, 0x81cc330 [ORD=17]
...

Until initial selection DAG, it looks fine. Let's look at dag after dag 
combine.
/* After dag combine, "s = x[0].b1 ? 1 : 0;" */
...
   0x81d17c0: i8,ch = load 0x81cca20, 0x81cbfb8, 
0x81cc0e0<LD1[%b12](align=2)> [ORD=14]

       0x81d17c0: <multiple use>
       --> 'and' was removed.
     0x81d1b38: i1 = truncate 0x81d17c0 [ORD=16]

     0x81d1c60: i32 = Constant<1>

     0x81cc330: <multiple use>
   0x81d1d88: i32 = select 0x81d1b38, 0x81d1c60, 0x81cc330 [ORD=17]
...

The target, which I am working, does not have i1's register class. It 
means that the 'truncate' is changed to its first operand 'load' during 
type legalize because it should be promoted. Therefore I have wanted to 
keep the 'and' to make correct 1 bit value. But dag combine pass is 
removing the 'and' on TargetLowering::SimplifyDemandedBits function. 
When I look at the function, even though the LHS does not have knownbit 
information, the code uses it with NewMask to compare LHS with RHS. Is 
it intended? Could someone explain it? If I missed something, please let 
me know.

Thanks,
JinGu Kang


More information about the llvm-dev mailing list