Skip to content

Commit

Permalink
[InstCombine] Fold trunc nuw/nsw (x xor y) to i1 to x != y (#90408)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
YanWQ-monad authored Apr 30, 2024
1 parent 2cb97c7 commit 34c89ef
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
6 changes: 6 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,12 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
return new ICmpInst(ICmpInst::Predicate::ICMP_EQ, X, Zero);
}
}

if (Trunc.hasNoUnsignedWrap() || Trunc.hasNoSignedWrap()) {
Value *X, *Y;
if (match(Src, m_Xor(m_Value(X), m_Value(Y))))
return new ICmpInst(ICmpInst::ICMP_NE, X, Y);
}
}

Value *A, *B;
Expand Down
41 changes: 41 additions & 0 deletions llvm/test/Transforms/InstCombine/trunc.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1054,3 +1054,44 @@ define i8 @drop_both_trunc(i16 %x, i16 %y) {
%res = trunc nuw nsw i16 %and2 to i8
ret i8 %res
}

define i1 @trunc_xor(i8 %x, i8 %y) {
; CHECK-LABEL: @trunc_xor(
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[R:%.*]] = trunc i8 [[XOR]] to i1
; CHECK-NEXT: ret i1 [[R]]
;
%xor = xor i8 %x, %y
%r = trunc i8 %xor to i1
ret i1 %r
}

define i1 @trunc_nuw_xor(i8 %x, i8 %y) {
; CHECK-LABEL: @trunc_nuw_xor(
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%xor = xor i8 %x, %y
%r = trunc nuw i8 %xor to i1
ret i1 %r
}

define i1 @trunc_nsw_xor(i8 %x, i8 %y) {
; CHECK-LABEL: @trunc_nsw_xor(
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%xor = xor i8 %x, %y
%r = trunc nsw i8 %xor to i1
ret i1 %r
}

define <2 x i1> @trunc_nuw_xor_vector(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @trunc_nuw_xor_vector(
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%xor = xor <2 x i8> %x, %y
%r = trunc nuw <2 x i8> %xor to <2 x i1>
ret <2 x i1> %r
}

0 comments on commit 34c89ef

Please sign in to comment.