Skip to content

Commit 34c89ef

Browse files
authored
[InstCombine] Fold trunc nuw/nsw (x xor y) to i1 to x != y (#90408)
Fold: ``` llvm define i1 @src(i8 %x, i8 %y) { %xor = xor i8 %x, %y %r = trunc nuw/nsw i8 %xor to i1 ret i1 %r } define i1 @tgt(i8 %x, i8 %y) { %r = icmp ne i8 %x, %y ret i1 %r } ``` Proof: https://alive2.llvm.org/ce/z/dcuHmn
1 parent 2cb97c7 commit 34c89ef

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,12 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
770770
return new ICmpInst(ICmpInst::Predicate::ICMP_EQ, X, Zero);
771771
}
772772
}
773+
774+
if (Trunc.hasNoUnsignedWrap() || Trunc.hasNoSignedWrap()) {
775+
Value *X, *Y;
776+
if (match(Src, m_Xor(m_Value(X), m_Value(Y))))
777+
return new ICmpInst(ICmpInst::ICMP_NE, X, Y);
778+
}
773779
}
774780

775781
Value *A, *B;

llvm/test/Transforms/InstCombine/trunc.ll

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,3 +1054,44 @@ define i8 @drop_both_trunc(i16 %x, i16 %y) {
10541054
%res = trunc nuw nsw i16 %and2 to i8
10551055
ret i8 %res
10561056
}
1057+
1058+
define i1 @trunc_xor(i8 %x, i8 %y) {
1059+
; CHECK-LABEL: @trunc_xor(
1060+
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]
1061+
; CHECK-NEXT: [[R:%.*]] = trunc i8 [[XOR]] to i1
1062+
; CHECK-NEXT: ret i1 [[R]]
1063+
;
1064+
%xor = xor i8 %x, %y
1065+
%r = trunc i8 %xor to i1
1066+
ret i1 %r
1067+
}
1068+
1069+
define i1 @trunc_nuw_xor(i8 %x, i8 %y) {
1070+
; CHECK-LABEL: @trunc_nuw_xor(
1071+
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
1072+
; CHECK-NEXT: ret i1 [[R]]
1073+
;
1074+
%xor = xor i8 %x, %y
1075+
%r = trunc nuw i8 %xor to i1
1076+
ret i1 %r
1077+
}
1078+
1079+
define i1 @trunc_nsw_xor(i8 %x, i8 %y) {
1080+
; CHECK-LABEL: @trunc_nsw_xor(
1081+
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
1082+
; CHECK-NEXT: ret i1 [[R]]
1083+
;
1084+
%xor = xor i8 %x, %y
1085+
%r = trunc nsw i8 %xor to i1
1086+
ret i1 %r
1087+
}
1088+
1089+
define <2 x i1> @trunc_nuw_xor_vector(<2 x i8> %x, <2 x i8> %y) {
1090+
; CHECK-LABEL: @trunc_nuw_xor_vector(
1091+
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[X:%.*]], [[Y:%.*]]
1092+
; CHECK-NEXT: ret <2 x i1> [[R]]
1093+
;
1094+
%xor = xor <2 x i8> %x, %y
1095+
%r = trunc nuw <2 x i8> %xor to <2 x i1>
1096+
ret <2 x i1> %r
1097+
}

0 commit comments

Comments
 (0)