|
From: <sv...@va...> - 2012-11-19 15:12:18
|
sewardj 2012-11-19 15:12:07 +0000 (Mon, 19 Nov 2012)
New Revision: 13129
Log:
Add test cases for dependency tracking through pmovmskb and bsfl.
Part of #308627. (Patrick J. LoPresti, lop...@gm...)
Added files:
trunk/memcheck/tests/amd64/insn-bsfl.c
trunk/memcheck/tests/amd64/insn-bsfl.stderr.exp
trunk/memcheck/tests/amd64/insn-bsfl.stdout.exp
trunk/memcheck/tests/amd64/insn-bsfl.vgtest
trunk/memcheck/tests/amd64/insn-pmovmskb.c
trunk/memcheck/tests/amd64/insn-pmovmskb.stderr.exp
trunk/memcheck/tests/amd64/insn-pmovmskb.stdout.exp
trunk/memcheck/tests/amd64/insn-pmovmskb.vgtest
Modified files:
trunk/memcheck/tests/amd64/Makefile.am
Added: trunk/memcheck/tests/amd64/insn-pmovmskb.vgtest (+2 -0)
===================================================================
--- trunk/memcheck/tests/amd64/insn-pmovmskb.vgtest 2012-11-19 14:55:15 +00:00 (rev 13128)
+++ trunk/memcheck/tests/amd64/insn-pmovmskb.vgtest 2012-11-19 15:12:07 +00:00 (rev 13129)
@@ -0,0 +1,2 @@
+prog: insn-pmovmskb
+vgopts: -q
Added: trunk/memcheck/tests/amd64/insn-pmovmskb.c (+147 -0)
===================================================================
--- trunk/memcheck/tests/amd64/insn-pmovmskb.c 2012-11-19 14:55:15 +00:00 (rev 13128)
+++ trunk/memcheck/tests/amd64/insn-pmovmskb.c 2012-11-19 15:12:07 +00:00 (rev 13129)
@@ -0,0 +1,147 @@
+/* https://bugs.kde.org/show_bug.cgi?id=308627 */
+
+#include "../../memcheck.h"
+
+#include <stdio.h>
+
+typedef unsigned long ULong;
+
+typedef struct {
+ ULong w64[2]; /* Note: little-endian */
+} V128;
+
+static int getMSBs16x8(V128 v)
+{
+ int result;
+ __asm__("movups %1,%%xmm6\n"
+ "\tpmovmskb %%xmm6,%0\n"
+ : "=r" (result) : "m" (v) : "xmm6");
+ return result;
+}
+
+/* Set the V bits on the data at "addr". Note the convention: A zero
+ bit means "defined"; 1 means "undefined". */
+static void set_vbits(V128 *addr, V128 vbits)
+{
+ int i;
+ for (i=0 ; i<2 ; ++i) {
+ VALGRIND_SET_VBITS(&addr->w64[i], &vbits.w64[i], sizeof(vbits.w64[i]));
+ }
+}
+
+static void print(V128 vbits, V128 val, int bit, int result)
+{
+ printf("vbits=0x%016lx%016lx val=0x%016lx%016lx bit=%d result=%d\n",
+ vbits.w64[1], vbits.w64[0], val.w64[1], val.w64[0],
+ bit, result);
+}
+
+/* Use a value that we know is invalid. */
+static void use(int index, int invalid)
+{
+ /* Convince GCC it does not know what is in "invalid" so it cannot
+ possibly optimize away the conditional branch below. */
+ __asm__ ("" : "=r" (invalid) : "0" (invalid));
+
+ /* Create a conditional branch on which our output depends, so that
+ memcheck cannot possibly optimize it away, either. */
+ fprintf(stderr, "%d: Invalid value is %s\n",
+ index, invalid ? "true" : "false");
+}
+
+static void doit(ULong vbits_hi, ULong vbits_lo, ULong val_hi, ULong val_lo)
+{
+ V128 vbits = { { vbits_lo, vbits_hi } };
+ V128 val = { { val_lo, val_hi } };
+
+ /* Since we are about to mark "val" partially undefined, make a
+ copy that we can use without generating a memcheck warning. */
+ V128 val_copy = val;
+
+ set_vbits(&val, vbits);
+
+ int result = getMSBs16x8(val);
+
+ int vbits_mask = getMSBs16x8(vbits);
+
+ int bit = 0; ULong mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 1; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 2; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 3; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 4; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 5; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 6 ; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 7 ; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 8 ; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 9 ; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 10 ; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 11 ; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 12 ; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 13 ; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 14 ; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+
+ bit = 15 ; mask = (1UL << bit);
+ if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
+ else use(bit, result & mask);
+}
+
+int main(int argc, char *argv[])
+{
+ doit(0x0000000000000000, 0x0000000000000000,
+ 0x0000000000000000, 0x0000000000000000);
+
+ doit(0x0707070707070707, 0x0707070707070707,
+ 0x0000000000000000, 0x0000000000000000);
+
+ doit(0x8080808080808080, 0x8080808080808080,
+ 0x0000000000000000, 0x0000000000000000);
+
+ doit(0x13579BDF02468ACE, 0xFEDCBA9876543210,
+ 0xFEEDFACEDEADBEEF, 0xFEE1DEADDABBAD00);
+
+ return 0;
+}
Added: trunk/memcheck/tests/amd64/insn-bsfl.stderr.exp (+40 -0)
===================================================================
--- trunk/memcheck/tests/amd64/insn-bsfl.stderr.exp 2012-11-19 14:55:15 +00:00 (rev 13128)
+++ trunk/memcheck/tests/amd64/insn-bsfl.stderr.exp 2012-11-19 15:12:07 +00:00 (rev 13129)
@@ -0,0 +1,40 @@
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: doit (insn-bsfl.c:47)
+ by 0x........: main (insn-bsfl.c:65)
+
+0x........: Invalid value is 32
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: doit (insn-bsfl.c:47)
+ by 0x........: main (insn-bsfl.c:66)
+
+0x........: Invalid value is 0
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: doit (insn-bsfl.c:47)
+ by 0x........: main (insn-bsfl.c:69)
+
+0x........: Invalid value is 6
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: doit (insn-bsfl.c:47)
+ by 0x........: main (insn-bsfl.c:73)
+
+0x........: Invalid value is 9
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: doit (insn-bsfl.c:47)
+ by 0x........: main (insn-bsfl.c:76)
+
+0x........: Invalid value is 17
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: doit (insn-bsfl.c:47)
+ by 0x........: main (insn-bsfl.c:79)
+
+0x........: Invalid value is 0
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: doit (insn-bsfl.c:47)
+ by 0x........: main (insn-bsfl.c:81)
+
+0x........: Invalid value is 1
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: doit (insn-bsfl.c:47)
+ by 0x........: main (insn-bsfl.c:82)
+
+0x........: Invalid value is 1
Added: trunk/memcheck/tests/amd64/insn-pmovmskb.stderr.exp (+144 -0)
===================================================================
--- trunk/memcheck/tests/amd64/insn-pmovmskb.stderr.exp 2012-11-19 14:55:15 +00:00 (rev 13128)
+++ trunk/memcheck/tests/amd64/insn-pmovmskb.stderr.exp 2012-11-19 15:12:07 +00:00 (rev 13129)
@@ -0,0 +1,144 @@
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:69)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+0: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:73)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+1: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:77)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+2: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:81)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+3: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:85)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+4: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:89)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+5: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:93)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+6: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:97)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+7: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:101)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+8: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:105)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+9: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:109)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+10: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:113)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+11: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:117)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+12: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:121)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+13: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:125)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+14: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:129)
+ by 0x........: main (insn-pmovmskb.c:140)
+
+15: Invalid value is false
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:85)
+ by 0x........: main (insn-pmovmskb.c:143)
+
+4: Invalid value is true
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:89)
+ by 0x........: main (insn-pmovmskb.c:143)
+
+5: Invalid value is true
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:93)
+ by 0x........: main (insn-pmovmskb.c:143)
+
+6: Invalid value is true
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:97)
+ by 0x........: main (insn-pmovmskb.c:143)
+
+7: Invalid value is true
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:101)
+ by 0x........: main (insn-pmovmskb.c:143)
+
+8: Invalid value is true
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:105)
+ by 0x........: main (insn-pmovmskb.c:143)
+
+9: Invalid value is true
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:117)
+ by 0x........: main (insn-pmovmskb.c:143)
+
+12: Invalid value is true
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: use (insn-pmovmskb.c:48)
+ by 0x........: doit (insn-pmovmskb.c:121)
+ by 0x........: main (insn-pmovmskb.c:143)
+
+13: Invalid value is true
Added: trunk/memcheck/tests/amd64/insn-bsfl.vgtest (+2 -0)
===================================================================
--- trunk/memcheck/tests/amd64/insn-bsfl.vgtest 2012-11-19 14:55:15 +00:00 (rev 13128)
+++ trunk/memcheck/tests/amd64/insn-bsfl.vgtest 2012-11-19 15:12:07 +00:00 (rev 13129)
@@ -0,0 +1,2 @@
+prog: insn-bsfl
+vgopts: -q
Added: trunk/memcheck/tests/amd64/insn-bsfl.stdout.exp (+6 -0)
===================================================================
--- trunk/memcheck/tests/amd64/insn-bsfl.stdout.exp 2012-11-19 14:55:15 +00:00 (rev 13128)
+++ trunk/memcheck/tests/amd64/insn-bsfl.stdout.exp 2012-11-19 15:12:07 +00:00 (rev 13129)
@@ -0,0 +1,6 @@
+vbits=0x00000000 ctz(0x00000000)=32
+vbits=0x00000000 ctz(0x00000001)=0
+vbits=0x00000040 ctz(0x00000090)=4
+vbits=0x00000a00 ctz(0x00000500)=8
+vbits=0x001e0000 ctz(0x000f0000)=16
+vbits=0xfffffffe ctz(0xffffffff)=0
Added: trunk/memcheck/tests/amd64/insn-pmovmskb.stdout.exp (+40 -0)
===================================================================
--- trunk/memcheck/tests/amd64/insn-pmovmskb.stdout.exp 2012-11-19 14:55:15 +00:00 (rev 13128)
+++ trunk/memcheck/tests/amd64/insn-pmovmskb.stdout.exp 2012-11-19 15:12:07 +00:00 (rev 13129)
@@ -0,0 +1,40 @@
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=0 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=1 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=2 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=3 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=4 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=5 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=6 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=7 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=8 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=9 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=10 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=11 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=12 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=13 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=14 result=0
+vbits=0x00000000000000000000000000000000 val=0x00000000000000000000000000000000 bit=15 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=0 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=1 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=2 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=3 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=4 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=5 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=6 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=7 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=8 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=9 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=10 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=11 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=12 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=13 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=14 result=0
+vbits=0x07070707070707070707070707070707 val=0x00000000000000000000000000000000 bit=15 result=0
+vbits=0x13579bdf02468acefedcba9876543210 val=0xfeedfacedeadbeeffee1deaddabbad00 bit=0 result=0
+vbits=0x13579bdf02468acefedcba9876543210 val=0xfeedfacedeadbeeffee1deaddabbad00 bit=1 result=2
+vbits=0x13579bdf02468acefedcba9876543210 val=0xfeedfacedeadbeeffee1deaddabbad00 bit=2 result=4
+vbits=0x13579bdf02468acefedcba9876543210 val=0xfeedfacedeadbeeffee1deaddabbad00 bit=3 result=8
+vbits=0x13579bdf02468acefedcba9876543210 val=0xfeedfacedeadbeeffee1deaddabbad00 bit=10 result=1024
+vbits=0x13579bdf02468acefedcba9876543210 val=0xfeedfacedeadbeeffee1deaddabbad00 bit=11 result=2048
+vbits=0x13579bdf02468acefedcba9876543210 val=0xfeedfacedeadbeeffee1deaddabbad00 bit=14 result=16384
+vbits=0x13579bdf02468acefedcba9876543210 val=0xfeedfacedeadbeeffee1deaddabbad00 bit=15 result=32768
Modified: trunk/memcheck/tests/amd64/Makefile.am (+2 -0)
===================================================================
--- trunk/memcheck/tests/amd64/Makefile.am 2012-11-19 14:55:15 +00:00 (rev 13128)
+++ trunk/memcheck/tests/amd64/Makefile.am 2012-11-19 15:12:07 +00:00 (rev 13129)
@@ -24,6 +24,8 @@
bug132146 \
bug279698 \
fxsave-amd64 \
+ insn-bsfl \
+ insn-pmovmskb \
more_x87_fp \
sse_memory \
xor-undef-amd64
Added: trunk/memcheck/tests/amd64/insn-bsfl.c (+85 -0)
===================================================================
--- trunk/memcheck/tests/amd64/insn-bsfl.c 2012-11-19 14:55:15 +00:00 (rev 13128)
+++ trunk/memcheck/tests/amd64/insn-bsfl.c 2012-11-19 15:12:07 +00:00 (rev 13129)
@@ -0,0 +1,85 @@
+/* https://bugs.kde.org/show_bug.cgi?id=308626 */
+
+#include "../../memcheck.h"
+
+#include <stdio.h>
+#include <assert.h>
+
+typedef unsigned int UInt;
+
+/* Calculate ctz(x) using bsfl instruction. */
+static int ctz(UInt x)
+{
+ assert(sizeof(UInt) == 4);
+ int result=8*sizeof(UInt);
+ /* BSFL does not change the destination when the input is zero. */
+ asm("bsfl %1,%0" : "=r" (result) : "r" (x), "0" (result) : "cc");
+ return result;
+}
+
+/* Set the V bits at "addr". Note the convention: A zero bit means
+ "defined"; 1 means "undefined". */
+static void set_vbits(UInt *addr, UInt vbits)
+{
+ VALGRIND_SET_VBITS(addr, &vbits, sizeof(unsigned));
+}
+
+static void doit(unsigned vbits, unsigned val)
+{
+ /* Since we are about to mark "val" partially undefined, make a
+ copy that we can use without generating a memcheck warning. */
+ unsigned val_copy = val;
+
+ /* Mark "val" partially undefined. */
+ set_vbits(&val, vbits);
+
+ /* Convince GCC it does not know what is in "val" so it does not
+ optimize away any uses of it. */
+ __asm__ ("" : "=r" (val) : "0" (val));
+
+ int result = ctz(val);
+
+ /* The following code is carefully constructed: The conditional
+ itself should generate a memcheck warning if and only if it is
+ false. (Specifically, if the first "1" bit in val comes before
+ the first "undefined" bit, or the entire word is valid, then
+ ctz(val) is defined; else it is undefined.) */
+ if (result < ctz(vbits) || vbits == 0) {
+ /* There should be no memcheck warning on this printf, since
+ "result" is fully-defined in this case. */
+ printf("vbits=0x%08x ctz(0x%08x)=%d\n", vbits, val_copy, result);
+ }
+ else {
+ /* memcheck should have output a warning. But we want
+ something here so there is no possibiliy of Valgrind
+ optimizing out the conditional itself. */
+ fprintf(stderr, "0x%08x: Invalid value is %d\n", val_copy,
+ ctz(val_copy));
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ doit(0x00000000, 0x00000000);
+ doit(0x00000000, 0x00000001);
+ doit(0x00000001, 0x00000000);
+ doit(0x00000001, 0x00000001);
+
+ /* valid bit / data bit sandwich */
+ doit(0x00000090, 0x00000040);
+ doit(0x00000040, 0x00000090);
+
+ /* Interleaving */
+ doit(0x00000500, 0x00000a00);
+ doit(0x00000a00, 0x00000500);
+
+ doit(0x000f0000, 0x001e0000);
+ doit(0x001e0000, 0x000f0000);
+
+ doit(0xffffffff, 0xffffffff);
+ doit(0xfffffffe, 0xffffffff);
+ doit(0xffffffff, 0xfffffffe);
+ doit(0xfffffffe, 0xfffffffe);
+
+ return 0;
+}
|