Files
clang-p2996/llvm/test/Transforms/InstCombine/min-positive.ll
Sanjay Patel 30be665e82 [PatternMatch] allow undef elements when matching a vector zero
This is the last step in getting constant pattern matchers to allow
undef elements in constant vectors.

I'm adding a dedicated m_ZeroInt() function and building m_Zero() from
that. In most cases, calling code can be updated to use m_ZeroInt()
directly when there's no need to match pointers, but I'm leaving that
efficiency optimization as a follow-up step because it's not always
clear when that's ok.

There are just enough icmp folds in InstSimplify that can be used for 
integer or pointer types, that we probably still want a generic m_Zero()
for those cases. Otherwise, we could eliminate it (and possibly add a
m_NullPtr() as an alias for isa<ConstantPointerNull>()).

We're conservatively returning a full zero vector (zeroinitializer) in
InstSimplify/InstCombine on some of these folds (see diffs in InstSimplify),
but I'm not sure if that's actually necessary in all cases. We may be 
able to propagate an undef lane instead. One test where this happens is 
marked with 'TODO'.
 

llvm-svn: 330550
2018-04-22 17:07:44 +00:00

102 lines
3.7 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -instcombine < %s | FileCheck %s
@g = external global i32
define i1 @smin(i32 %other) {
; CHECK-LABEL: @smin(
; CHECK-NEXT: [[TEST:%.*]] = icmp sgt i32 [[OTHER:%.*]], 0
; CHECK-NEXT: ret i1 [[TEST]]
;
%positive = load i32, i32* @g, !range !{i32 1, i32 2048}
%cmp = icmp slt i32 %positive, %other
%sel = select i1 %cmp, i32 %positive, i32 %other
%test = icmp sgt i32 %sel, 0
ret i1 %test
}
; Range metadata doesn't work for vectors, so find another way to trigger isKnownPositive().
define <2 x i1> @smin_vec(<2 x i32> %x, <2 x i32> %other) {
; CHECK-LABEL: @smin_vec(
; CHECK-NEXT: [[TEST:%.*]] = icmp sgt <2 x i32> [[OTHER:%.*]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[TEST]]
;
%notneg = and <2 x i32> %x, <i32 7, i32 7>
%positive = or <2 x i32> %notneg, <i32 1, i32 1>
%cmp = icmp slt <2 x i32> %positive, %other
%sel = select <2 x i1> %cmp, <2 x i32> %positive, <2 x i32> %other
%test = icmp sgt <2 x i32> %sel, zeroinitializer
ret <2 x i1> %test
}
define i1 @smin_commute(i32 %other) {
; CHECK-LABEL: @smin_commute(
; CHECK-NEXT: [[TEST:%.*]] = icmp sgt i32 [[OTHER:%.*]], 0
; CHECK-NEXT: ret i1 [[TEST]]
;
%positive = load i32, i32* @g, !range !{i32 1, i32 2048}
%cmp = icmp slt i32 %other, %positive
%sel = select i1 %cmp, i32 %other, i32 %positive
%test = icmp sgt i32 %sel, 0
ret i1 %test
}
define <2 x i1> @smin_commute_vec(<2 x i32> %x, <2 x i32> %other) {
; CHECK-LABEL: @smin_commute_vec(
; CHECK-NEXT: [[TEST:%.*]] = icmp sgt <2 x i32> [[OTHER:%.*]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[TEST]]
;
%notneg = and <2 x i32> %x, <i32 7, i32 7>
%positive = or <2 x i32> %notneg, <i32 1, i32 1>
%cmp = icmp slt <2 x i32> %other, %positive
%sel = select <2 x i1> %cmp, <2 x i32> %other, <2 x i32> %positive
%test = icmp sgt <2 x i32> %sel, zeroinitializer
ret <2 x i1> %test
}
define <2 x i1> @smin_commute_vec_undef_elts(<2 x i32> %x, <2 x i32> %other) {
; CHECK-LABEL: @smin_commute_vec_undef_elts(
; CHECK-NEXT: [[TEST:%.*]] = icmp sgt <2 x i32> [[OTHER:%.*]], <i32 0, i32 undef>
; CHECK-NEXT: ret <2 x i1> [[TEST]]
;
%notneg = and <2 x i32> %x, <i32 7, i32 7>
%positive = or <2 x i32> %notneg, <i32 1, i32 1>
%cmp = icmp slt <2 x i32> %other, %positive
%sel = select <2 x i1> %cmp, <2 x i32> %other, <2 x i32> %positive
%test = icmp sgt <2 x i32> %sel, <i32 0, i32 undef>
ret <2 x i1> %test
}
; %positive might be zero
define i1 @maybe_not_positive(i32 %other) {
; CHECK-LABEL: @maybe_not_positive(
; CHECK-NEXT: [[POSITIVE:%.*]] = load i32, i32* @g, align 4, !range !0
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[POSITIVE]], [[OTHER:%.*]]
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[POSITIVE]], i32 [[OTHER]]
; CHECK-NEXT: [[TEST:%.*]] = icmp sgt i32 [[SEL]], 0
; CHECK-NEXT: ret i1 [[TEST]]
;
%positive = load i32, i32* @g, !range !{i32 0, i32 2048}
%cmp = icmp slt i32 %positive, %other
%sel = select i1 %cmp, i32 %positive, i32 %other
%test = icmp sgt i32 %sel, 0
ret i1 %test
}
define <2 x i1> @maybe_not_positive_vec(<2 x i32> %x, <2 x i32> %other) {
; CHECK-LABEL: @maybe_not_positive_vec(
; CHECK-NEXT: [[NOTNEG:%.*]] = and <2 x i32> [[X:%.*]], <i32 7, i32 7>
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[NOTNEG]], [[OTHER:%.*]]
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[NOTNEG]], <2 x i32> [[OTHER]]
; CHECK-NEXT: [[TEST:%.*]] = icmp sgt <2 x i32> [[SEL]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[TEST]]
;
%notneg = and <2 x i32> %x, <i32 7, i32 7>
%cmp = icmp slt <2 x i32> %notneg, %other
%sel = select <2 x i1> %cmp, <2 x i32> %notneg, <2 x i32> %other
%test = icmp sgt <2 x i32> %sel, zeroinitializer
ret <2 x i1> %test
}