1/* https://bugs.kde.org/show_bug.cgi?id=308627 */ 2 3#include "../../memcheck.h" 4 5#include <stdio.h> 6 7typedef unsigned long ULong; 8 9typedef struct { 10 ULong w64[2]; /* Note: little-endian */ 11} V128; 12 13static int getMSBs16x8(V128 v) 14{ 15 int result; 16 __asm__("movups %1,%%xmm6\n" 17 "\tpmovmskb %%xmm6,%0\n" 18 : "=r" (result) : "m" (v) : "xmm6"); 19 return result; 20} 21 22/* Set the V bits on the data at "addr". Note the convention: A zero 23 bit means "defined"; 1 means "undefined". */ 24static void set_vbits(V128 *addr, V128 vbits) 25{ 26 int i; 27 for (i=0 ; i<2 ; ++i) { 28 (void)VALGRIND_SET_VBITS(&addr->w64[i], &vbits.w64[i], sizeof(vbits.w64[i])); 29 } 30} 31 32static void print(V128 vbits, V128 val, int bit, int result) 33{ 34 printf("vbits=0x%016lx%016lx val=0x%016lx%016lx bit=%d result=%d\n", 35 vbits.w64[1], vbits.w64[0], val.w64[1], val.w64[0], 36 bit, result); 37} 38 39/* Use a value that we know is invalid. */ 40static void use(int index, int invalid) 41{ 42 /* Convince GCC it does not know what is in "invalid" so it cannot 43 possibly optimize away the conditional branch below. */ 44 __asm__ ("" : "=r" (invalid) : "0" (invalid)); 45 46 /* Create a conditional branch on which our output depends, so that 47 memcheck cannot possibly optimize it away, either. */ 48 fprintf(stderr, "%d: Invalid value is %s\n", 49 index, invalid ? "true" : "false"); 50} 51 52static void doit(ULong vbits_hi, ULong vbits_lo, ULong val_hi, ULong val_lo) 53{ 54 V128 vbits = { { vbits_lo, vbits_hi } }; 55 V128 val = { { val_lo, val_hi } }; 56 57 /* Since we are about to mark "val" partially undefined, make a 58 copy that we can use without generating a memcheck warning. */ 59 V128 val_copy = val; 60 61 set_vbits(&val, vbits); 62 63 int result = getMSBs16x8(val); 64 65 int vbits_mask = getMSBs16x8(vbits); 66 67 int bit = 0; ULong mask = (1UL << bit); 68 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 69 else use(bit, result & mask); 70 71 bit = 1; mask = (1UL << bit); 72 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 73 else use(bit, result & mask); 74 75 bit = 2; mask = (1UL << bit); 76 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 77 else use(bit, result & mask); 78 79 bit = 3; mask = (1UL << bit); 80 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 81 else use(bit, result & mask); 82 83 bit = 4; mask = (1UL << bit); 84 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 85 else use(bit, result & mask); 86 87 bit = 5; mask = (1UL << bit); 88 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 89 else use(bit, result & mask); 90 91 bit = 6 ; mask = (1UL << bit); 92 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 93 else use(bit, result & mask); 94 95 bit = 7 ; mask = (1UL << bit); 96 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 97 else use(bit, result & mask); 98 99 bit = 8 ; mask = (1UL << bit); 100 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 101 else use(bit, result & mask); 102 103 bit = 9 ; mask = (1UL << bit); 104 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 105 else use(bit, result & mask); 106 107 bit = 10 ; mask = (1UL << bit); 108 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 109 else use(bit, result & mask); 110 111 bit = 11 ; mask = (1UL << bit); 112 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 113 else use(bit, result & mask); 114 115 bit = 12 ; mask = (1UL << bit); 116 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 117 else use(bit, result & mask); 118 119 bit = 13 ; mask = (1UL << bit); 120 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 121 else use(bit, result & mask); 122 123 bit = 14 ; mask = (1UL << bit); 124 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 125 else use(bit, result & mask); 126 127 bit = 15 ; mask = (1UL << bit); 128 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 129 else use(bit, result & mask); 130} 131 132int main(int argc, char *argv[]) 133{ 134 doit(0x0000000000000000, 0x0000000000000000, 135 0x0000000000000000, 0x0000000000000000); 136 137 doit(0x0707070707070707, 0x0707070707070707, 138 0x0000000000000000, 0x0000000000000000); 139 140 doit(0x8080808080808080, 0x8080808080808080, 141 0x0000000000000000, 0x0000000000000000); 142 143 doit(0x13579BDF02468ACE, 0xFEDCBA9876543210, 144 0xFEEDFACEDEADBEEF, 0xFEE1DEADDABBAD00); 145 146 return 0; 147} 148