[PATCH] D72423: [DemandedBits] Improve accuracy of Add propagator

Erika via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 9 02:20:10 PST 2020


rrika added a comment.

By exhaustive test you mean an .ll file, or a program looping over all values? In the process of writing this I found a mistake (the final '+1' only applies to additions, not subtractions) so I'll edit the patch in a bit.

  // exhaustive test for add demand propagator on 4 bit integers
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <stdint.h>
  typedef uint8_t u8;
  typedef uint8_t u16;
  typedef uint32_t u32;
  
  u8 flip_nybble[256] = {
  	0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE, 0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF
  };
  
  static int mode; // 0=add 1=sub
  static u8 a, b, ka, kb, aout;
  static u8 aa, ab;
  
  void fail (int x, int y) {
  	u8 ab = 0xf & (mode ? a-b : a+b);
  	u8 xy = 0xf & (mode ? x-y : x+y);
  	char c = mode ? '-' : '+';
  	printf(
  		"propagator failed:\n"
  		"  a=%01x ka=%01x aa=%01x   x=%01x\n"
  		"  b=%01x kb=%01x ab=%01x   y=%01x\n"
  		"a%cb=%01x    aout=%01x x%cy=%01x\n",
  		a, ka, aa, x,
  		b, kb, ab, y,
  		c, ab, aout, c, xy
  	);
  	exit(1);
  }
  
  void confirm_add (u8 x, u8 y) {
  	x = (x & ~aa) | a; // a and x match in alive bits
  	y = (y & ~ab) | b; // b and y match in alive bits
  	int ok = (((a+b) ^ (x+y)) & aout) == 0; // then a+b and x+y must match in alive bits
  	if (!ok)
  		fail(x, y);
  }
  
  void confirm_sub (u8 x, u8 y) {
  	x = (x & ~aa) | a; // a and x match in alive bits
  	y = (y & ~ab) | b; // b and y match in alive bits
  	int ok = (((a-b) ^ (x-y)) & aout) == 0; // then a-b and x-y must match in alive bits
  	if (!ok)
  		fail(x, y);
  }
  
  void confirm_adds () {
  	for (u32 xy=0; xy < 256; xy++) {
  		u8 x = (xy >> 0) & 0xf;
  		u8 y = (xy >> 4) & 0xf;
  		confirm_add(x, y);
  	}
  }
  
  void confirm_subs () {
  	for (u32 xy=0; xy < 256; xy++) {
  		u8 x = (xy >> 0) & 0xf;
  		u8 y = (xy >> 4) & 0xf;
  		confirm_sub(x, y);
  	}
  }
  
  
  int main (int argc, char **argv) {
  	(void) argc;
  	(void) argv;
  	for (mode=0; mode<2; mode++) // 0 = add, 1 = sub
  	for (u32 t=0; t < 0x100000; t++) {
  		a    = (t >>  0) & 0xf;
  		b    = (t >>  4) & 0xf;
  		ka   = (t >>  8) & 0xf;
  		kb   = (t >> 12) & 0xf;
  		aout = (t >> 16) & 0xf;
  
  		u8 a0 = ~a & ka;
  		u8 a1 =  a & ka;
  		u8 b0 = ~b & kb;
  		u8 b1 =  b & kb;
  
  		// now the propagator
  		u8 bound1 = a0;
  		u8 bound2 = mode ? b1 : b0;
  		u8 bound = bound1 & bound2;
  		u8 rbound = flip_nybble[bound];
  		u8 raout = flip_nybble[aout];
  		u8 rprop = raout + (raout | ~rbound);
  		u8 rq = (rprop ^ ~(raout | rbound));
  		rq &= 0xf;
  
  		u8 q = flip_nybble[rq];
  		u8 ua = bound1 | ~bound2;
  		u8 ub = bound2 | ~bound1;
  		aa = aout | (q & (ua | (bound1 + bound2 + (mode?0:1))));
  		ab = aout | (q & (ub | (bound1 + bound2 + (mode?0:1))));
  
  		aa &= 0xf;
  		ab &= 0xf;
  
  		if (mode == 0)
  			confirm_adds(a, b, aa, ab, aout);
  		else
  			confirm_subs(a, b, aa, ab, aout);
  	}
  	return 0;
  }


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72423/new/

https://reviews.llvm.org/D72423





More information about the llvm-commits mailing list