mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 20:29:53 +00:00
a2db716bbb
The benefits of this change include: 1. Remove DeMorgan-matching code that was added specifically to work-around the missing transform in http://reviews.llvm.org/rL248634. 2. Makes the DeMorgan transform work for vectors too. 3. Fix PR28476: https://llvm.org/bugs/show_bug.cgi?id=28476 Extending this transform to other casts and other associative operators may be useful too. See https://reviews.llvm.org/D22421 for a prerequisite for doing that though. Differential Revision: https://reviews.llvm.org/D22271 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@276221 91177308-0d34-0410-b5e6-96231b3b80d8
82 lines
2.7 KiB
LLVM
82 lines
2.7 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -instcombine -S | FileCheck %s
|
|
|
|
; PR22723: Recognize De Morgan's Laws when obfuscated by zexts.
|
|
|
|
define i32 @demorgan_or(i1 %X, i1 %Y) {
|
|
; CHECK-LABEL: @demorgan_or(
|
|
; CHECK-NEXT: [[OR1_DEMORGAN:%.*]] = and i1 %X, %Y
|
|
; CHECK-NEXT: [[OR1:%.*]] = xor i1 [[OR1_DEMORGAN]], true
|
|
; CHECK-NEXT: [[OR:%.*]] = zext i1 [[OR:%.*]]1 to i32
|
|
; CHECK-NEXT: ret i32 [[OR]]
|
|
;
|
|
%zextX = zext i1 %X to i32
|
|
%zextY = zext i1 %Y to i32
|
|
%notX = xor i32 %zextX, 1
|
|
%notY = xor i32 %zextY, 1
|
|
%or = or i32 %notX, %notY
|
|
ret i32 %or
|
|
}
|
|
|
|
define i32 @demorgan_and(i1 %X, i1 %Y) {
|
|
; CHECK-LABEL: @demorgan_and(
|
|
; CHECK-NEXT: [[AND1_DEMORGAN:%.*]] = or i1 %X, %Y
|
|
; CHECK-NEXT: [[AND1:%.*]] = xor i1 [[AND1_DEMORGAN]], true
|
|
; CHECK-NEXT: [[AND:%.*]] = zext i1 [[AND:%.*]]1 to i32
|
|
; CHECK-NEXT: ret i32 [[AND]]
|
|
;
|
|
%zextX = zext i1 %X to i32
|
|
%zextY = zext i1 %Y to i32
|
|
%notX = xor i32 %zextX, 1
|
|
%notY = xor i32 %zextY, 1
|
|
%and = and i32 %notX, %notY
|
|
ret i32 %and
|
|
}
|
|
|
|
define <2 x i32> @demorgan_or_vec(<2 x i1> %X, <2 x i1> %Y) {
|
|
; CHECK-LABEL: @demorgan_or_vec(
|
|
; CHECK-NEXT: [[OR1_DEMORGAN:%.*]] = and <2 x i1> %X, %Y
|
|
; CHECK-NEXT: [[OR1:%.*]] = xor <2 x i1> [[OR1_DEMORGAN]], <i1 true, i1 true>
|
|
; CHECK-NEXT: [[OR:%.*]] = zext <2 x i1> [[OR:%.*]]1 to <2 x i32>
|
|
; CHECK-NEXT: ret <2 x i32> [[OR]]
|
|
;
|
|
%zextX = zext <2 x i1> %X to <2 x i32>
|
|
%zextY = zext <2 x i1> %Y to <2 x i32>
|
|
%notX = xor <2 x i32> %zextX, <i32 1, i32 1>
|
|
%notY = xor <2 x i32> %zextY, <i32 1, i32 1>
|
|
%or = or <2 x i32> %notX, %notY
|
|
ret <2 x i32> %or
|
|
}
|
|
|
|
define <2 x i32> @demorgan_and_vec(<2 x i1> %X, <2 x i1> %Y) {
|
|
; CHECK-LABEL: @demorgan_and_vec(
|
|
; CHECK-NEXT: [[AND1_DEMORGAN:%.*]] = or <2 x i1> %X, %Y
|
|
; CHECK-NEXT: [[AND1:%.*]] = xor <2 x i1> [[AND1_DEMORGAN]], <i1 true, i1 true>
|
|
; CHECK-NEXT: [[AND:%.*]] = zext <2 x i1> [[AND:%.*]]1 to <2 x i32>
|
|
; CHECK-NEXT: ret <2 x i32> [[AND]]
|
|
;
|
|
%zextX = zext <2 x i1> %X to <2 x i32>
|
|
%zextY = zext <2 x i1> %Y to <2 x i32>
|
|
%notX = xor <2 x i32> %zextX, <i32 1, i32 1>
|
|
%notY = xor <2 x i32> %zextY, <i32 1, i32 1>
|
|
%and = and <2 x i32> %notX, %notY
|
|
ret <2 x i32> %and
|
|
}
|
|
|
|
define i32 @PR28476(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @PR28476(
|
|
; CHECK-NEXT: [[NOTLHS:%.*]] = icmp eq i32 %x, 0
|
|
; CHECK-NEXT: [[NOTRHS:%.*]] = icmp eq i32 %y, 0
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[NOTRHS]], [[NOTLHS]]
|
|
; CHECK-NEXT: [[COND:%.*]] = zext i1 [[TMP1]] to i32
|
|
; CHECK-NEXT: ret i32 [[COND]]
|
|
;
|
|
%cmp0 = icmp ne i32 %x, 0
|
|
%cmp1 = icmp ne i32 %y, 0
|
|
%and = and i1 %cmp0, %cmp1
|
|
%zext = zext i1 %and to i32
|
|
%cond = xor i32 %zext, 1
|
|
ret i32 %cond
|
|
}
|
|
|