Skip to content

Commit 48c88e6

Browse files
committed
[InstCombine] Fold Xor with or disjoint
Implement a missing optimization to fold (A | B) ^ C to (A ^ C) ^ B
1 parent b69c03f commit 48c88e6

File tree

4 files changed

+26
-17
lines changed

4 files changed

+26
-17
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4706,6 +4706,15 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
47064706
return Xor;
47074707

47084708
Value *X, *Y;
4709+
4710+
// (A | B) ^ C -> (A ^ C) ^ B
4711+
// C ^ (A | B) -> B ^ (A ^ C)
4712+
if (match(&I, m_c_Xor(m_OneUse(m_c_DisjointOr(m_Value(X), m_Value(Y))),
4713+
m_Value(M)))) {
4714+
Value *XorAC = Builder.CreateXor(X, M);
4715+
return BinaryOperator::CreateXor(XorAC, Y);
4716+
}
4717+
47094718
Constant *C1;
47104719
if (match(Op1, m_Constant(C1))) {
47114720
Constant *C2;

llvm/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ define i8 @foo(i8 %arg, i8 %arg1) {
3333
; CHECK-NEXT: [[T4:%.*]] = and i8 [[ARG1]], 33
3434
; CHECK-NEXT: [[T5:%.*]] = sub nsw i8 40, [[T2]]
3535
; CHECK-NEXT: [[T6:%.*]] = and i8 [[T5]], 84
36-
; CHECK-NEXT: [[T7:%.*]] = or disjoint i8 [[T4]], [[T6]]
3736
; CHECK-NEXT: [[T8:%.*]] = xor i8 [[T]], [[T3]]
38-
; CHECK-NEXT: [[T9:%.*]] = or disjoint i8 [[T7]], [[T8]]
3937
; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[T8]], 2
4038
; CHECK-NEXT: [[T11:%.*]] = and i8 [[TMP1]], 32
41-
; CHECK-NEXT: [[T12:%.*]] = xor i8 [[T11]], [[T9]]
39+
; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[T4]], [[T11]]
40+
; CHECK-NEXT: [[TMP3:%.*]] = or disjoint i8 [[TMP2]], [[T6]]
41+
; CHECK-NEXT: [[T12:%.*]] = or disjoint i8 [[TMP3]], [[T8]]
4242
; CHECK-NEXT: ret i8 [[T12]]
4343
;
4444
%t = shl i8 %arg, 7

llvm/test/Transforms/InstCombine/icmp-of-xor-x.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,8 @@ define i1 @xor_ugt_2(i8 %xx, i8 %y, i8 %z) {
358358
; CHECK-LABEL: @xor_ugt_2(
359359
; CHECK-NEXT: [[X:%.*]] = add i8 [[XX:%.*]], [[Z:%.*]]
360360
; CHECK-NEXT: [[YZ:%.*]] = and i8 [[Y:%.*]], 63
361-
; CHECK-NEXT: [[Y1:%.*]] = or disjoint i8 [[YZ]], 64
362-
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X]], [[Y1]]
361+
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[YZ]], [[X]]
362+
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[TMP1]], 64
363363
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[XOR]]
364364
; CHECK-NEXT: ret i1 [[R]]
365365
;
@@ -385,8 +385,8 @@ define i1 @xor_ult(i8 %x) {
385385
define <2 x i1> @xor_sgt(<2 x i8> %x, <2 x i8> %y) {
386386
; CHECK-LABEL: @xor_sgt(
387387
; CHECK-NEXT: [[YZ:%.*]] = and <2 x i8> [[Y:%.*]], <i8 31, i8 31>
388-
; CHECK-NEXT: [[Y1:%.*]] = or disjoint <2 x i8> [[YZ]], <i8 64, i8 64>
389-
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i8> [[X:%.*]], [[Y1]]
388+
; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i8> [[YZ]], [[X:%.*]]
389+
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i8> [[TMP1]], <i8 64, i8 64>
390390
; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i8> [[XOR]], [[X]]
391391
; CHECK-NEXT: ret <2 x i1> [[R]]
392392
;
@@ -400,8 +400,8 @@ define <2 x i1> @xor_sgt(<2 x i8> %x, <2 x i8> %y) {
400400
define <2 x i1> @xor_sgt_fail_no_known_msb(<2 x i8> %x, <2 x i8> %y) {
401401
; CHECK-LABEL: @xor_sgt_fail_no_known_msb(
402402
; CHECK-NEXT: [[YZ:%.*]] = and <2 x i8> [[Y:%.*]], <i8 55, i8 55>
403-
; CHECK-NEXT: [[Y1:%.*]] = or disjoint <2 x i8> [[YZ]], <i8 8, i8 8>
404-
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i8> [[X:%.*]], [[Y1]]
403+
; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i8> [[YZ]], [[X:%.*]]
404+
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i8> [[TMP1]], <i8 8, i8 8>
405405
; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i8> [[XOR]], [[X]]
406406
; CHECK-NEXT: ret <2 x i1> [[R]]
407407
;

llvm/test/Transforms/InstCombine/xor.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,8 +1489,8 @@ define i4 @PR96857_xor_without_noundef(i4 %val0, i4 %val1, i4 %val2) {
14891489
define i32 @or_disjoint_with_xor(i32 %a, i32 %b, i32 %c) {
14901490
; CHECK-LABEL: @or_disjoint_with_xor(
14911491
; CHECK-NEXT: entry:
1492-
; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[A:%.*]], [[B:%.*]]
1493-
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[OR]], [[C:%.*]]
1492+
; CHECK-NEXT: [[TMP0:%.*]] = xor i32 [[A:%.*]], [[C:%.*]]
1493+
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP0]], [[B:%.*]]
14941494
; CHECK-NEXT: ret i32 [[XOR]]
14951495
;
14961496
entry:
@@ -1502,8 +1502,8 @@ entry:
15021502
define i32 @xor_with_or_disjoint(i32 %a, i32 %b, i32 %c) {
15031503
; CHECK-LABEL: @xor_with_or_disjoint(
15041504
; CHECK-NEXT: entry:
1505-
; CHECK-NEXT: [[OR:%.*]] = or disjoint i32 [[A:%.*]], [[B:%.*]]
1506-
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[C:%.*]], [[OR]]
1505+
; CHECK-NEXT: [[TMP0:%.*]] = xor i32 [[A:%.*]], [[C:%.*]]
1506+
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP0]], [[B:%.*]]
15071507
; CHECK-NEXT: ret i32 [[XOR]]
15081508
;
15091509
entry:
@@ -1515,8 +1515,8 @@ entry:
15151515
define <2 x i32> @or_disjoint_with_xor_vec(<2 x i32> %a, < 2 x i32> %b, <2 x i32> %c) {
15161516
; CHECK-LABEL: @or_disjoint_with_xor_vec(
15171517
; CHECK-NEXT: entry:
1518-
; CHECK-NEXT: [[OR:%.*]] = or disjoint <2 x i32> [[A:%.*]], [[B:%.*]]
1519-
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[OR]], [[C:%.*]]
1518+
; CHECK-NEXT: [[TMP0:%.*]] = xor <2 x i32> [[A:%.*]], [[C:%.*]]
1519+
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[TMP0]], [[B:%.*]]
15201520
; CHECK-NEXT: ret <2 x i32> [[XOR]]
15211521
;
15221522
entry:
@@ -1528,8 +1528,8 @@ entry:
15281528
define <2 x i32> @xor_with_or_disjoint_vec(<2 x i32> %a, < 2 x i32> %b, <2 x i32> %c) {
15291529
; CHECK-LABEL: @xor_with_or_disjoint_vec(
15301530
; CHECK-NEXT: entry:
1531-
; CHECK-NEXT: [[OR:%.*]] = or disjoint <2 x i32> [[A:%.*]], [[B:%.*]]
1532-
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[C:%.*]], [[OR]]
1531+
; CHECK-NEXT: [[TMP0:%.*]] = xor <2 x i32> [[A:%.*]], [[C:%.*]]
1532+
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[TMP0]], [[B:%.*]]
15331533
; CHECK-NEXT: ret <2 x i32> [[XOR]]
15341534
;
15351535
entry:

0 commit comments

Comments
 (0)