Index: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td +++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td @@ -1680,6 +1680,11 @@ (i32 63)), (Select64 (LGHI -1), (LGHI 0), imm32zx4:$valid, imm32zx4:$cc)>; +// Avoid generating 2 XOR instructions. (xor (and x, y), y) is +// equivalent to (and (xor x, -1), y) +def : Pat<(and (xor GR64:$x, (i64 -1)), GR64:$y), + (XGR GR64:$y, (NGR GR64:$y, GR64:$x))>; + // Peepholes for turning scalar operations into block operations. defm : BlockLoadStore; Index: llvm/trunk/test/CodeGen/SystemZ/and-xor-01.ll =================================================================== --- llvm/trunk/test/CodeGen/SystemZ/and-xor-01.ll +++ llvm/trunk/test/CodeGen/SystemZ/and-xor-01.ll @@ -0,0 +1,14 @@ +; Testing peephole for generating shorter code for (and (xor b, -1), a) +; +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +define i64 @f1(i64 %a, i64 %b) { +; CHECK-LABEL: f1: +; CHECK: ngr %r3, %r2 +; CHECK: xgr %r2, %r3 +; CHECK: br %r14 + %neg = xor i64 %b, -1 + %and = and i64 %neg, %a + ret i64 %and +} +