Because cc == 3 cannot occur the rightmost bit of cond is
a don't care.
*/
+ if (isC64(cc_dep2)) {
+ /* Avoid memcheck false positives for comparisons like `<= 0x1f',
+ `> 0x1f', `< 0x20', or `>= 0x20', where the lower bits don't
+ matter. Some compiler optimizations yield such comparisons when
+ testing if any (or none) of the upper bits are set. */
+
+ ULong mask = cc_dep2->Iex.Const.con->Ico.U64;
+ ULong c = cond & (8 + 4 + 2);
+
+ if ((mask & (mask - 1)) == 0) {
+ /* Transform `< 0x20' to `<= 0x1f' and
+ `>= 0x20' to `> 0x1f' */
+ mask -= 1;
+ c ^= 8;
+ }
+ if (mask != 0 && (mask + 1) != 0 && (mask & (mask + 1)) == 0 &&
+ (c == 8 + 4 || c == 2)) {
+ IROp cmp = c == 8 + 4 ? Iop_CmpEQ64 : Iop_CmpNE64;
+ return unop(Iop_1Uto32,
+ binop(cmp, binop(Iop_And64, cc_dep1, mkU64(~mask)),
+ mkU64(0)));
+ }
+ }
if (cond == 8 || cond == 8 + 1) {
return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, cc_dep2));
}
dist_noinst_SCRIPTS = filter_stderr
-INSN_TESTS = cdsg cu21 cu42 ltgjhe vstrc vfae vistr vstrs
+INSN_TESTS = cdsg cli cu21 cu42 ltgjhe vstrc vfae vistr vstrs
check_PROGRAMS = $(INSN_TESTS)
--- /dev/null
+#include <stdlib.h>
+
+volatile unsigned long tmp;
+static const char use_idx[] = "01234567890abcdefghijklmnopqrstuvwxyz";
+
+static void depend_on(int val) { tmp = use_idx[val]; }
+
+static void pretend_write(unsigned long* val) { __asm__("" : "=m"(*val) : :); }
+
+static void do_compares(unsigned long value)
+{
+ unsigned char val1 = value & 0xff;
+ int result = 0;
+
+ __asm__("cli %[val],0x20\n\t"
+ "jl 1f\n\t"
+ "lghi %[res],1\n\t"
+ "1: nopr 0"
+ : [res] "+d"(result)
+ : [val] "Q"(val1)
+ :);
+ depend_on(result);
+
+ __asm__("cli %[val],0x40\n\t"
+ "jnl 1f\n\t"
+ "lghi %[res],2\n\t"
+ "1: nopr 0"
+ : [res] "+d"(result)
+ : [val] "Q"(val1)
+ :);
+ depend_on(result);
+}
+
+int main()
+{
+ unsigned long* buf = malloc(sizeof(unsigned long));
+ pretend_write(buf);
+ do_compares(*buf & 0x3f);
+ free(buf);
+ return 0;
+}