[sil-simplify] Add a peephole for XOR

Use the following equality: (x xor y) xor y == x.
With this in mind (a xor b) xor c can be replaced by:
 a - if b and c are the same
 b - if a and c are the same
 c - if a and b are the same

rdar://20280322

Swift SVN r26568
This commit is contained in:
Roman Levenstein
2015-03-26 00:37:08 +00:00
parent 381e9ebe40
commit f8a1aaff96
2 changed files with 67 additions and 0 deletions

View File

@@ -488,6 +488,29 @@ static SILValue simplifyBuiltin(BuiltinInst *BI) {
} }
return SILValue(); return SILValue();
} }
case BuiltinValueKind::Xor: {
SILValue val1, val2, val3;
// xor (xor (val1, val2), val3) == val1
if (BI->getNumOperands() == 2 &&
(match(BI,
m_BuiltinInst(BuiltinValueKind::Xor,
m_BuiltinInst(BuiltinValueKind::Xor,
m_SILValue(val1), m_SILValue(val2)),
m_SILValue(val3))) ||
match(BI, m_BuiltinInst(BuiltinValueKind::Xor, m_SILValue(val3),
m_BuiltinInst(BuiltinValueKind::Xor,
m_SILValue(val1),
m_SILValue(val2)))))) {
if (val2 == val3)
return val1.getDef();
if (val1 == val3)
return val2.getDef();
if (val1 == val2)
return val3.getDef();
}
}
} }
return SILValue(); return SILValue();
} }

View File

@@ -176,3 +176,47 @@ bb2:
bb3(%11 : $Ternary): bb3(%11 : $Ternary):
return %11 : $Ternary return %11 : $Ternary
} }
// xor(xor (a, b), b) -> a
// CHECK-LABEL: sil @simplify_xor1
// CHECK-NEXT: bb0
// CHECK-NEXT: %[[ID:[0-9+]]] = integer_literal $Builtin.Int32, 1
// CHECK-NEXT: return %[[ID]] : $Builtin.Int32
sil @simplify_xor1 : $@thin () -> Builtin.Int32 {
bb0:
%0 = integer_literal $Builtin.Int32, 1
%1 = integer_literal $Builtin.Int32, 21
%2 = builtin "xor_Int32"(%0 : $Builtin.Int32, %1 : $Builtin.Int32) : $Builtin.Int32
%3 = builtin "xor_Int32"(%2 : $Builtin.Int32, %1 : $Builtin.Int32) : $Builtin.Int32
return %3 : $Builtin.Int32
}
// xor(xor (a, b), a) -> b
// CHECK-LABEL: sil @simplify_xor2
// CHECK-NEXT: bb0
// CHECK-NEXT: %[[ID:[0-9+]]] = integer_literal $Builtin.Int32, 21
// CHECK-NEXT: return %[[ID]] : $Builtin.Int32
sil @simplify_xor2 : $@thin () -> Builtin.Int32 {
bb0:
%0 = integer_literal $Builtin.Int32, 1
%1 = integer_literal $Builtin.Int32, 21
%2 = builtin "xor_Int32"(%0 : $Builtin.Int32, %1 : $Builtin.Int32) : $Builtin.Int32
%3 = builtin "xor_Int32"(%2 : $Builtin.Int32, %0 : $Builtin.Int32) : $Builtin.Int32
return %3 : $Builtin.Int32
}
// CHECK-LABEL: sil @simplify_xor3
// CHECK-NEXT: bb0
// CHECK-NEXT: %[[ID:[0-9+]]] = integer_literal $Builtin.Int32, 1
// CHECK-NEXT: return %[[ID]] : $Builtin.Int32
// xor(b, xor (a, b)) -> a
sil @simplify_xor3 : $@thin () -> Builtin.Int32 {
bb0:
%0 = integer_literal $Builtin.Int32, 1
%1 = integer_literal $Builtin.Int32, 21
%2 = builtin "xor_Int32"(%0 : $Builtin.Int32, %1 : $Builtin.Int32) : $Builtin.Int32
%3 = builtin "xor_Int32"(%1 : $Builtin.Int32, %2 : $Builtin.Int32) : $Builtin.Int32
return %3 : $Builtin.Int32
}