Page MenuHomePhabricator

File Metadata

Author
aarzee
Created
May 5 2016, 10:57 AM

floattestgen.py

import itertools
import subprocess
import multiprocessing
import sys
import os
opt = '/Users/aarzee/llvmbuild/bin/opt'
lli = '/Users/aarzee/llvmbuild/bin/lli'
boolean = [[True, False]]
def bitrestrict(ilen):
for bits in itertools.product('01U', repeat=ilen):
if 'U' in bits:
yield bits
def setbit(orig, bitpos, bitwidth):
if bitpos == bitwidth - 1:
orig -= 2 ** (ilen - 1)
else:
orig += 2 ** bitpos
return orig
def bitrestrictnums(bits, ilen):
notzero = 0
one = 0
for i, bit in enumerate(reversed(bits)):
if bit == 'U':
notzero = setbit(notzero, i, ilen)
if bit == '1':
one = setbit(one, i, ilen)
return (notzero, one)
def funccast(bits, ilen, fptype):
itype = 'i' + str(ilen)
func = 'define ' + itype + ' @test1(' + itype + ' %A) {\n'
cvar = '%A'
if bits[0] != -1 * 2 ** ilen:
func += ' %B = and ' + itype + ' ' + cvar + ', ' + str(bits[0]) + '\n'
cvar = '%B'
if bits[1] != 0:
func += ' %C = or ' + itype + ' ' + cvar + ', ' + str(bits[1]) + '\n'
cvar = '%C'
func += ' %D = sitofp ' + itype + ' ' + cvar + ' to ' + fptype + '\n'
func += ' %E = fptosi ' + fptype + ' %D to ' + itype + '\n'
func += ' ret ' + itype + ' %E\n'
func += '}\n'
return func
def funcnocast(bits, ilen):
itype = 'i' + str(ilen)
func = 'define ' + itype + ' @test2(' + itype + ' %A) {\n'
cvar = '%A'
if bits[0] != -1 * 2 ** ilen:
func += ' %B = and ' + itype + ' ' + cvar + ', ' + str(bits[0]) + '\n'
cvar = '%B'
if bits[1] != 0:
func += ' %C = or ' + itype + ' ' + cvar + ', ' + str(bits[1]) + '\n'
cvar = '%C'
func += ' ret ' + itype + ' ' + cvar + '\n'
func += '}\n'
return func
def funccmp(ilen):
itype = 'i' + str(ilen)
func = 'define i1 @testcmp(' + itype + ' %A) {\n'
func += ' %B = call ' + itype + ' @test1(' + itype + ' %A)\n'
func += ' %C = call ' + itype + ' @test2(' + itype + ' %A)\n'
func += ' %D = icmp eq ' + itype + ' %B, %C\n'
func += ' ret i1 %D\n'
func += '}\n'
return func
def actuallydothing(tup):
num = tup[2]
bits = tup[0]
ilen = len(bits)
ubits = []
for i, b in enumerate(reversed(bits)):
if b == 'U':
ubits.append(i)
itype = 'i' + str(ilen)
fptype = tup[1]
nums = bitrestrictnums(bits, ilen)
fc = funccast(nums, ilen, fptype)
bfc = bytes(fc, 'utf-8')
osp = subprocess.Popen([opt, '-instcombine', '-S', '-'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
ofc, _ = osp.communicate(input=bfc)
nottriggered = b'sitofp' in ofc
text = fc
text += funcnocast(nums, ilen)
text += funccmp(ilen)
text += 'define i32 @main() {\n'
text += ' br label %eq0l\n'
i = 0
for bools in itertools.product(*boolean * len(ubits)):
text += 'eq' + str(i) + 'l:\n'
t = 0
for j, b in enumerate(bools):
if b:
t = setbit(t, ubits[j], ilen)
text += ' %eq' + str(i) + ' = call i1 @testcmp(' + itype + ' ' + str(t) + ')\n'
text += ' br i1 %eq' + str(i) + ', label %eq' + str(i + 1) + 'l, label %fail\n'
i += 1
text += 'eq' + str(i) + 'l:\n'
text += ' ret i32 0\n'
text += 'fail:\n'
text += ' ret i32 1\n'
text += '}\n'
run = subprocess.Popen([lli, '-O0'], stdin=subprocess.PIPE)
run.communicate(bytes(text, 'utf-8'))
if bool(run.returncode) != nottriggered:
print('Exit code (' + str(run.returncode) + ') doesn\'t match with optimization (' + ('not ' if nottriggered else '') + 'triggered)')
with open('ex' + str(num) + '.ll', 'w') as ex:
ex.write('; ' + ''.join(bits) + ' (should ' + ('fail' if nottriggered else 'succeed') + ')\n' + text)
print('Failed comparison IR output to ex' + str(num) + '.ll')
def functest(ilen, fptype):
pool = multiprocessing.Pool()
tups = []
tupslen = 3 ** ilen - 2 ** ilen
print('Testing ' + str(tupslen) + ' programs... (this will take a while)')
for i, bits in enumerate(bitrestrict(ilen)):
pool.apply_async(actuallydothing, (bits, fptype, i))
pool.close()
pool.join()
print('Tested ' + str(tupslen) + ' programs')
functest(16, 'half')
# 16 is width of integer type, 'half' is float type. Width should be the width
# of float type or greater
# Note that the number of programs generated grows *exponentially* (3^x - 2^x)
# I would not recommend trying anything higher than 20 if you value your time

Event Timeline