blob: 44bb4ecaf8fa2df551e92735510722893f0f5a18 [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instcombine -S | FileCheck %s
declare void @use(i8)
define i1 @ult_2(i32 %x) {
; CHECK-LABEL: @ult_2(
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 254
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[TMP1]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
%r = icmp ult i8 %t, 2
ret i1 %r
}
define <2 x i1> @ult_16_splat(<2 x i16> %x) {
; CHECK-LABEL: @ult_16_splat(
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], <i16 2032, i16 2032>
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i16> [[TMP1]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%t = trunc <2 x i16> %x to <2 x i11>
%r = icmp ult <2 x i11> %t, <i11 16, i11 16>
ret <2 x i1> %r
}
; negative test - need power-of-2 constant
define i1 @ult_3(i32 %x) {
; CHECK-LABEL: @ult_3(
; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[T]], 3
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
%r = icmp ult i8 %t, 3
ret i1 %r
}
; negative test - no extra use allowed
define i1 @ult_2_use(i32 %x) {
; CHECK-LABEL: @ult_2_use(
; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
; CHECK-NEXT: call void @use(i8 [[T]])
; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[T]], 2
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
call void @use(i8 %t)
%r = icmp ult i8 %t, 2
ret i1 %r
}
@a = internal unnamed_addr constant [3 x i32] [i32 0, i32 0, i32 1], align 4
define i1 @PR52260(i32 %x) {
; CHECK-LABEL: @PR52260(
; CHECK-NEXT: ret i1 true
;
%idxprom = sext i32 %x to i64
%idx = getelementptr inbounds [3 x i32], [3 x i32]* @a, i64 0, i64 %idxprom
%t1 = load i32, i32* %idx, align 4
%conv1 = lshr i32 %t1, 1
%t2 = trunc i32 %conv1 to i8
%conv2 = and i8 %t2, 127
%tobool = icmp eq i8 %conv2, 0
ret i1 %tobool
}
define i1 @ult_192(i32 %x) {
; CHECK-LABEL: @ult_192(
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 192
; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[TMP1]], 192
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
%r = icmp ult i8 %t, 192 ; 0b1100_0000
ret i1 %r
}
define <2 x i1> @ult_2044_splat(<2 x i16> %x) {
; CHECK-LABEL: @ult_2044_splat(
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], <i16 2044, i16 2044>
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i16> [[TMP1]], <i16 2044, i16 2044>
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%t = trunc <2 x i16> %x to <2 x i11>
%r = icmp ult <2 x i11> %t, <i11 2044, i11 2044> ; 0b111_1111_1100
ret <2 x i1> %r
}
; negative test - need high-bit-mask constant
define i1 @ult_96(i32 %x) {
; CHECK-LABEL: @ult_96(
; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[T]], 96
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
%r = icmp ult i8 %t, 96 ; 0b0110_0000
ret i1 %r
}
; negative test - no extra use allowed
define i1 @ult_192_use(i32 %x) {
; CHECK-LABEL: @ult_192_use(
; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
; CHECK-NEXT: call void @use(i8 [[T]])
; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[T]], -64
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
call void @use(i8 %t)
%r = icmp ult i8 %t, 192
ret i1 %r
}
define i1 @ugt_3(i32 %x) {
; CHECK-LABEL: @ugt_3(
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 252
; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[TMP1]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
%r = icmp ugt i8 %t, 3
ret i1 %r
}
define <2 x i1> @ugt_7_splat(<2 x i16> %x) {
; CHECK-LABEL: @ugt_7_splat(
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], <i16 2040, i16 2040>
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i16> [[TMP1]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%t = trunc <2 x i16> %x to <2 x i11>
%r = icmp ugt <2 x i11> %t, <i11 7, i11 7>
ret <2 x i1> %r
}
; negative test - need low-bit-mask constant
define i1 @ugt_4(i32 %x) {
; CHECK-LABEL: @ugt_4(
; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[T]], 4
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
%r = icmp ugt i8 %t, 4
ret i1 %r
}
; negative test - no extra use allowed
define i1 @ugt_3_use(i32 %x) {
; CHECK-LABEL: @ugt_3_use(
; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
; CHECK-NEXT: call void @use(i8 [[T]])
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[T]], 3
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
call void @use(i8 %t)
%r = icmp ugt i8 %t, 3
ret i1 %r
}
define i1 @ugt_253(i32 %x) {
; CHECK-LABEL: @ugt_253(
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 254
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[TMP1]], 254
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
%r = icmp ugt i8 %t, 253
ret i1 %r
}
define <2 x i1> @ugt_2043_splat(<2 x i16> %x) {
; CHECK-LABEL: @ugt_2043_splat(
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], <i16 2044, i16 2044>
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i16> [[TMP1]], <i16 2044, i16 2044>
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%t = trunc <2 x i16> %x to <2 x i11>
%r = icmp ugt <2 x i11> %t, <i11 2043, i11 2043> ; 0b111_1111_101
ret <2 x i1> %r
}
; negative test - need not-of-power-of-2 constant
define i1 @ugt_252(i32 %x) {
; CHECK-LABEL: @ugt_252(
; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[T]], -4
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
%r = icmp ugt i8 %t, 252
ret i1 %r
}
; negative test - no extra use allowed
define i1 @ugt_253_use(i32 %x) {
; CHECK-LABEL: @ugt_253_use(
; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
; CHECK-NEXT: call void @use(i8 [[T]])
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[T]], -3
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
call void @use(i8 %t)
%r = icmp ugt i8 %t, 253
ret i1 %r
}
define i1 @slt_0(i32 %x) {
; CHECK-LABEL: @slt_0(
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 128
; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[TMP1]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
%r = icmp slt i8 %t, 0
ret i1 %r
}
define <2 x i1> @slt_0_splat(<2 x i16> %x) {
; CHECK-LABEL: @slt_0_splat(
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], <i16 1024, i16 1024>
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i16> [[TMP1]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%t = trunc <2 x i16> %x to <2 x i11>
%r = icmp slt <2 x i11> %t, zeroinitializer
ret <2 x i1> %r
}
define i1 @slt_1(i32 %x) {
; CHECK-LABEL: @slt_1(
; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[T]], 1
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
%r = icmp slt i8 %t, 1
ret i1 %r
}
define i1 @slt_0_use(i32 %x) {
; CHECK-LABEL: @slt_0_use(
; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
; CHECK-NEXT: call void @use(i8 [[T]])
; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[T]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
call void @use(i8 %t)
%r = icmp slt i8 %t, 0
ret i1 %r
}
define i1 @sgt_n1(i32 %x) {
; CHECK-LABEL: @sgt_n1(
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 128
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[TMP1]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
%r = icmp sgt i8 %t, -1
ret i1 %r
}
define <2 x i1> @sgt_n1_splat(<2 x i16> %x) {
; CHECK-LABEL: @sgt_n1_splat(
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], <i16 1024, i16 1024>
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i16> [[TMP1]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%t = trunc <2 x i16> %x to <2 x i11>
%r = icmp sgt <2 x i11> %t, <i11 -1, i11 -1>
ret <2 x i1> %r
}
define i1 @sgt_0(i32 %x) {
; CHECK-LABEL: @sgt_0(
; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[T]], 0
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
%r = icmp sgt i8 %t, 0
ret i1 %r
}
define i1 @sgt_n1_use(i32 %x) {
; CHECK-LABEL: @sgt_n1_use(
; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
; CHECK-NEXT: call void @use(i8 [[T]])
; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[T]], -1
; CHECK-NEXT: ret i1 [[R]]
;
%t = trunc i32 %x to i8
call void @use(i8 %t)
%r = icmp sgt i8 %t, -1
ret i1 %r
}