2020-04-18 02:05:04 +08:00
|
|
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
|
|
; RUN: opt < %s -instsimplify -S | FileCheck %s
|
|
|
|
|
|
|
|
; There are 12 basic patterns (or 6 with DeMorganized equivalent) with
|
|
|
|
; 2 (commute logic op) *
|
|
|
|
; 2 (swap compare operands) *
|
|
|
|
; 2 (signed/unsigned)
|
|
|
|
; variations for a total of 96 tests.
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;
|
|
|
|
; (X == MAX) && (X < Y) --> false
|
|
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
define i1 @slt_and_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @slt_and_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp slt i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 127
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define <2 x i1> @slt_and_max_commute(<2 x i8> %x, <2 x i8> %y) {
|
|
|
|
; CHECK-LABEL: @slt_and_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq <2 x i8> [[X]], <i8 127, i8 127>
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp slt <2 x i8> %x, %y
|
|
|
|
%cmpeq = icmp eq <2 x i8> %x, <i8 127, i8 127>
|
|
|
|
%r = and <2 x i1> %cmpeq, %cmp
|
|
|
|
ret <2 x i1> %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @slt_swap_and_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @slt_swap_and_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sgt i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 127
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @slt_swap_and_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @slt_swap_and_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sgt i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 127
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ult_and_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ult_and_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ult i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 255
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ult_and_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ult_and_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ult i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 255
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ult_swap_and_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ult_swap_and_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ugt i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 255
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ult_swap_and_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ult_swap_and_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ugt i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 255
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;
|
|
|
|
; (X == MIN) && (X > Y) --> false
|
|
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
define i1 @sgt_and_min(i9 %x, i9 %y) {
|
|
|
|
; CHECK-LABEL: @sgt_and_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i9 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i9 [[X]], -256
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sgt i9 %x, %y
|
|
|
|
%cmpeq = icmp eq i9 %x, 256
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sgt_and_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sgt_and_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sgt i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 128
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sgt_swap_and_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sgt_swap_and_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp slt i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 128
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sgt_swap_and_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sgt_swap_and_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp slt i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 128
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ugt_and_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ugt_and_min(
|
|
|
|
; CHECK-NEXT: ret i1 false
|
|
|
|
;
|
|
|
|
%cmp = icmp ugt i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 0
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ugt_and_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ugt_and_min_commute(
|
|
|
|
; CHECK-NEXT: ret i1 false
|
|
|
|
;
|
|
|
|
%cmp = icmp ugt i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 0
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ugt_swap_and_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ugt_swap_and_min(
|
|
|
|
; CHECK-NEXT: ret i1 false
|
|
|
|
;
|
|
|
|
%cmp = icmp ult i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 0
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ugt_swap_and_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ugt_swap_and_min_commute(
|
|
|
|
; CHECK-NEXT: ret i1 false
|
|
|
|
;
|
|
|
|
%cmp = icmp ult i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 0
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;
|
|
|
|
; (X != MAX) || (X >= Y) --> true
|
|
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
define i1 @sge_or_not_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sge_or_not_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sge i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 127
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sge_or_not_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sge_or_not_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sge i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 127
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sge_swap_or_not_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sge_swap_or_not_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sle i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 127
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sge_swap_or_not_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sge_swap_or_not_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sle i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 127
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @uge_or_not_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @uge_or_not_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp uge i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 255
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @uge_or_not_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @uge_or_not_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp uge i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 255
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @uge_swap_or_not_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @uge_swap_or_not_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ule i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 255
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @uge_swap_or_not_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @uge_swap_or_not_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ule i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 255
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;
|
|
|
|
; (X != MIN) || (X <= Y) --> true
|
|
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
define i1 @sle_or_not_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sle_or_not_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sle i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 128
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sle_or_not_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sle_or_not_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sle i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 128
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sle_swap_or_not_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sle_swap_or_not_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sge i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 128
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sle_swap_or_not_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sle_swap_or_not_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sge i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 128
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ule_or_not_min(i427 %x, i427 %y) {
|
|
|
|
; CHECK-LABEL: @ule_or_not_min(
|
|
|
|
; CHECK-NEXT: ret i1 true
|
|
|
|
;
|
|
|
|
%cmp = icmp ule i427 %x, %y
|
|
|
|
%cmpeq = icmp ne i427 %x, 0
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ule_or_not_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ule_or_not_min_commute(
|
|
|
|
; CHECK-NEXT: ret i1 true
|
|
|
|
;
|
|
|
|
%cmp = icmp ule i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 0
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ule_swap_or_not_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ule_swap_or_not_min(
|
|
|
|
; CHECK-NEXT: ret i1 true
|
|
|
|
;
|
|
|
|
%cmp = icmp uge i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 0
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ule_swap_or_not_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ule_swap_or_not_min_commute(
|
|
|
|
; CHECK-NEXT: ret i1 true
|
|
|
|
;
|
|
|
|
%cmp = icmp uge i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 0
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;
|
|
|
|
; (X == MAX) && (X >= Y) --> X == MAX
|
|
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
define i1 @sge_and_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sge_and_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sge i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 127
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sge_and_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sge_and_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sge i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 127
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sge_swap_and_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sge_swap_and_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sle i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 127
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sge_swap_and_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sge_swap_and_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sle i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 127
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @uge_and_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @uge_and_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp uge i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 255
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @uge_and_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @uge_and_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp uge i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 255
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @uge_swap_and_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @uge_swap_and_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ule i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 255
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @uge_swap_and_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @uge_swap_and_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ule i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 255
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;
|
|
|
|
; (X == MIN) && (X <= Y) --> X == MIN
|
|
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
define i1 @sle_and_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sle_and_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sle i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 128
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sle_and_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sle_and_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sle i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 128
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sle_swap_and_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sle_swap_and_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sge i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 128
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sle_swap_and_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sle_swap_and_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sge i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 128
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ule_and_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ule_and_min(
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 0
|
|
|
|
; CHECK-NEXT: ret i1 [[CMPEQ]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ule i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 0
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ule_and_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ule_and_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 0
|
|
|
|
; CHECK-NEXT: ret i1 [[CMPEQ]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ule i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 0
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ule_swap_and_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ule_swap_and_min(
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 0
|
|
|
|
; CHECK-NEXT: ret i1 [[CMPEQ]]
|
|
|
|
;
|
|
|
|
%cmp = icmp uge i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 0
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ule_swap_and_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ule_swap_and_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 0
|
|
|
|
; CHECK-NEXT: ret i1 [[CMPEQ]]
|
|
|
|
;
|
|
|
|
%cmp = icmp uge i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 0
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;
|
|
|
|
; (X == MAX) || (X >= Y) --> X >= Y
|
|
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
define i1 @sge_or_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sge_or_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp sge i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 127
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sge_or_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sge_or_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp sge i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 127
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sge_swap_or_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sge_swap_or_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[Y:%.*]], [[X:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp sle i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 127
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sge_swap_or_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sge_swap_or_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[Y:%.*]], [[X:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp sle i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 127
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @uge_or_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @uge_or_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp uge i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 255
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @uge_or_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @uge_or_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp uge i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 255
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @uge_swap_or_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @uge_swap_or_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp ule i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 255
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @uge_swap_or_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @uge_swap_or_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp ule i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 255
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;
|
|
|
|
; (X == MIN) || (X <= Y) --> X <= Y
|
|
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
define i1 @sle_or_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sle_or_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp sle i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 128
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sle_or_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sle_or_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp sle i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 128
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sle_swap_or_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sle_swap_or_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[Y:%.*]], [[X:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp sge i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 128
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sle_swap_or_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sle_swap_or_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[Y:%.*]], [[X:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp sge i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 128
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ule_or_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ule_or_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ule i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 0
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ule_or_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ule_or_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ule i8 %x, %y
|
|
|
|
%cmpeq = icmp eq i8 %x, 0
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ule_swap_or_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ule_swap_or_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
|
|
;
|
|
|
|
%cmp = icmp uge i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 0
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ule_swap_or_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ule_swap_or_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
|
|
;
|
|
|
|
%cmp = icmp uge i8 %y, %x
|
|
|
|
%cmpeq = icmp eq i8 %x, 0
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;
|
|
|
|
; (X != MAX) && (X < Y) --> X < Y
|
|
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
define i1 @slt_and_not_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @slt_and_not_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp slt i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 127
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @slt_and_not_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @slt_and_not_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp slt i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 127
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @slt_swap_and_not_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @slt_swap_and_not_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[Y:%.*]], [[X:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp sgt i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 127
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @slt_swap_and_not_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @slt_swap_and_not_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[Y:%.*]], [[X:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp sgt i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 127
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ult_and_not_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ult_and_not_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp ult i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 255
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ult_and_not_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ult_and_not_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp ult i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 255
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ult_swap_and_not_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ult_swap_and_not_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[Y:%.*]], [[X:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp ugt i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 255
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ult_swap_and_not_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ult_swap_and_not_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[Y:%.*]], [[X:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp ugt i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 255
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;
|
|
|
|
; (X != MIN) && (X > Y) --> X > Y
|
|
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
define i1 @sgt_and_not_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sgt_and_not_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp sgt i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 128
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sgt_and_not_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sgt_and_not_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp sgt i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 128
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sgt_swap_and_not_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sgt_swap_and_not_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp slt i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 128
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sgt_swap_and_not_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sgt_swap_and_not_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
|
[InstSimplify] fold and/or of compares with equality to min/max constant
I found 12 (6 if we compress the DeMorganized forms) patterns for logic-of-compares
with a min/max constant while looking at PR45510:
https://bugs.llvm.org/show_bug.cgi?id=45510
The variations on those forms multiply the test cases by 8 (unsigned/signed, swapped
compare operands, commuted logic operands).
We have partial logic to deal with these for the unsigned min (zero) case, but
missed everything else.
We are deferring the majority of these patterns to InstCombine to allow more general
handling (see D78582).
We could use ConstantRange instead of predicate+constant matching here. I don't
expect there's any noticeable compile-time impact for either form.
Here's an abuse of Alive2 to show the 12 basic signed variants of the patterns in
one function:
http://volta.cs.utah.edu:8080/z/5Vpiyg
declare void @use(i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1)
define void @src(i8 %x, i8 %y) {
%m1 = icmp eq i8 %x, 127
%c1 = icmp slt i8 %x, %y
%r1 = and i1 %m1, %c1 ; (X == MAX) && (X < Y) --> false
%m2 = icmp ne i8 %x, 127
%c2 = icmp sge i8 %x, %y
%r2 = or i1 %m2, %c2 ; (X != MAX) || (X >= Y) --> true
%m3 = icmp eq i8 %x, -128
%c3 = icmp sgt i8 %x, %y
%r3 = and i1 %m3, %c3 ; (X == MIN) && (X > Y) --> false
%m4 = icmp ne i8 %x, -128
%c4 = icmp sle i8 %x, %y
%r4 = or i1 %m4, %c4 ; (X != MIN) || (X <= Y) --> true
%m5 = icmp eq i8 %x, 127
%c5 = icmp sge i8 %x, %y
%r5 = and i1 %m5, %c5 ; (X == MAX) && (X >= Y) --> X == MAX
%m6 = icmp ne i8 %x, 127
%c6 = icmp slt i8 %x, %y
%r6 = or i1 %m6, %c6 ; (X != MAX) || (X < Y) --> X != MAX
%m7 = icmp eq i8 %x, -128
%c7 = icmp sle i8 %x, %y
%r7 = and i1 %m7, %c7 ; (X == MIN) && (X <= Y) --> X == MIN
%m8 = icmp ne i8 %x, -128
%c8 = icmp sgt i8 %x, %y
%r8 = or i1 %m8, %c8 ; (X != MIN) || (X > Y) --> X != MIN
%m9 = icmp ne i8 %x, 127
%c9 = icmp slt i8 %x, %y
%r9 = and i1 %m9, %c9 ; (X != MAX) && (X < Y) --> X < Y
%m10 = icmp eq i8 %x, 127
%c10 = icmp sge i8 %x, %y
%r10 = or i1 %m10, %c10 ; (X == MAX) || (X >= Y) --> X >= Y
%m11 = icmp ne i8 %x, -128
%c11 = icmp sgt i8 %x, %y
%r11 = and i1 %m11, %c11 ; (X != MIN) && (X > Y) --> X > Y
%m12 = icmp eq i8 %x, -128
%c12 = icmp sle i8 %x, %y
%r12 = or i1 %m12, %c12 ; (X == MIN) || (X <= Y) --> X <= Y
call void @use(i1 %r1, i1 %r2, i1 %r3, i1 %r4, i1 %r5, i1 %r6, i1 %r7, i1 %r8, i1 %r9, i1 %r10, i1 %r11, i1 %r12)
ret void
}
define void @tgt(i8 %x, i8 %y) {
%m5 = icmp eq i8 %x, 127
%m6 = icmp ne i8 %x, 127
%m7 = icmp eq i8 %x, -128
%m8 = icmp ne i8 %x, -128
%c9 = icmp slt i8 %x, %y
%c10 = icmp sge i8 %x, %y
%c11 = icmp sgt i8 %x, %y
%c12 = icmp sle i8 %x, %y
call void @use(i1 0, i1 1, i1 0, i1 1, i1 %m5, i1 %m6, i1 %m7, i1 %m8, i1 %c9, i1 %c10, i1 %c11, i1 %c12)
ret void
}
Differential Revision: https://reviews.llvm.org/D78430
2020-04-23 21:10:23 +08:00
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2020-04-18 02:05:04 +08:00
|
|
|
;
|
|
|
|
%cmp = icmp slt i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 128
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ugt_and_not_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ugt_and_not_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ugt i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 0
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ugt_and_not_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ugt_and_not_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ugt i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 0
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ugt_swap_and_not_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ugt_swap_and_not_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ult i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 0
|
|
|
|
%r = and i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ugt_swap_and_not_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ugt_swap_and_not_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ult i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 0
|
|
|
|
%r = and i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;
|
|
|
|
; (X != MAX) || (X < Y) --> X != MAX
|
|
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
define i1 @slt_or_not_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @slt_or_not_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp slt i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 127
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @slt_or_not_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @slt_or_not_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp slt i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 127
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @slt_swap_or_not_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @slt_swap_or_not_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sgt i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 127
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @slt_swap_or_not_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @slt_swap_or_not_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], 127
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sgt i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 127
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ult_or_not_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ult_or_not_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ult i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 255
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ult_or_not_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ult_or_not_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ult i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 255
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ult_swap_or_not_max(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ult_swap_or_not_max(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ugt i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 255
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ult_swap_or_not_max_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ult_swap_or_not_max_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -1
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ugt i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 255
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;
|
|
|
|
; (X != MIN) || (X > Y) --> X != MIN
|
|
|
|
;
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
define i1 @sgt_or_not_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sgt_or_not_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sgt i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 128
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sgt_or_not_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sgt_or_not_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp sgt i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 128
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sgt_swap_or_not_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sgt_swap_or_not_min(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp slt i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 128
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @sgt_swap_or_not_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @sgt_swap_or_not_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X]], -128
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMPEQ]], [[CMP]]
|
|
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
|
|
;
|
|
|
|
%cmp = icmp slt i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 128
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ugt_or_not_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ugt_or_not_min(
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 0
|
|
|
|
; CHECK-NEXT: ret i1 [[CMPEQ]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ugt i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 0
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ugt_or_not_min_commute(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ugt_or_not_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 0
|
|
|
|
; CHECK-NEXT: ret i1 [[CMPEQ]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ugt i8 %x, %y
|
|
|
|
%cmpeq = icmp ne i8 %x, 0
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ugt_swap_or_not_min(i8 %x, i8 %y) {
|
|
|
|
; CHECK-LABEL: @ugt_swap_or_not_min(
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 0
|
|
|
|
; CHECK-NEXT: ret i1 [[CMPEQ]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ult i8 %y, %x
|
|
|
|
%cmpeq = icmp ne i8 %x, 0
|
|
|
|
%r = or i1 %cmp, %cmpeq
|
|
|
|
ret i1 %r
|
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @ugt_swap_or_not_min_commute(i823 %x, i823 %y) {
|
|
|
|
; CHECK-LABEL: @ugt_swap_or_not_min_commute(
|
|
|
|
; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne i823 [[X:%.*]], 0
|
|
|
|
; CHECK-NEXT: ret i1 [[CMPEQ]]
|
|
|
|
;
|
|
|
|
%cmp = icmp ult i823 %y, %x
|
|
|
|
%cmpeq = icmp ne i823 %x, 0
|
|
|
|
%r = or i1 %cmpeq, %cmp
|
|
|
|
ret i1 %r
|
|
|
|
}
|