[llvm] [InstCombine] simplify `icmp pred x, ~x` (PR #73990)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 21 11:37:48 PDT 2024
https://github.com/ParkHanbum updated https://github.com/llvm/llvm-project/pull/73990
>From 614372e79db3bdef55658206b0986e155ef7605c Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Fri, 1 Dec 2023 06:28:23 +0900
Subject: [PATCH 1/2] [InstCombine] Add test for simplify `X comp X^Neg_C`
This patch add testcase for comparison between X and X^Neg_X.
comparison between X and X^Neg_C is determined solely by
presence of the sign bit, so we can simplify it to checking
whether X is negative or not.
---
.../Transforms/InstCombine/icmp-of-xor-x.ll | 904 ++++++++++++++++++
1 file changed, 904 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/icmp-of-xor-x.ll b/llvm/test/Transforms/InstCombine/icmp-of-xor-x.ll
index fd61c8a301662e..96ef7ce727d9cd 100644
--- a/llvm/test/Transforms/InstCombine/icmp-of-xor-x.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-of-xor-x.ll
@@ -5,6 +5,910 @@ declare void @llvm.assume(i1)
declare void @barrier()
declare void @use.i8(i8)
+; X comp X^Neg_C tests, signed.
+; X s< X^Neg_C --> X s< 0
+define i1 @src_slt_allone(i8 %x) {
+; CHECK-LABEL: @src_slt_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -1
+ %cmp = icmp slt i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_slt_min(i8 %x) {
+; CHECK-LABEL: @src_slt_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -128
+ %cmp = icmp slt i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_slt_i128_allone(i128 %x) {
+; CHECK-LABEL: @src_slt_i128_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -1
+ %cmp = icmp slt i128 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_slt_i128_min(i128 %x) {
+; CHECK-LABEL: @src_slt_i128_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -170141183460469231731687303715884105728
+ %cmp = icmp slt i128 %x, %not
+ ret i1 %cmp
+}
+
+; X s> X^Neg_C --> X s> -1
+define i1 @src_sgt_allone(i8 %x) {
+; CHECK-LABEL: @src_sgt_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -1
+ %cmp = icmp sgt i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_sgt_min(i8 %x) {
+; CHECK-LABEL: @src_sgt_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -128
+ %cmp = icmp sgt i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_sgt_i128_allone(i128 %x) {
+; CHECK-LABEL: @src_sgt_i128_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -1
+ %cmp = icmp sgt i128 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_sgt_i128_min(i128 %x) {
+; CHECK-LABEL: @src_sgt_i128_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -170141183460469231731687303715884105728
+ %cmp = icmp sgt i128 %x, %not
+ ret i1 %cmp
+}
+
+; X s<= X^Neg_C --> X s< 0
+define i1 @src_sle_allone(i8 %x) {
+; CHECK-LABEL: @src_sle_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -1
+ %cmp = icmp sle i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_sle_min(i8 %x) {
+; CHECK-LABEL: @src_sle_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -128
+ %cmp = icmp sle i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_sle_i128_allone(i128 %x) {
+; CHECK-LABEL: @src_sle_i128_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -1
+ %cmp = icmp sle i128 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_sle_i128_min(i128 %x) {
+; CHECK-LABEL: @src_sle_i128_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -170141183460469231731687303715884105728
+ %cmp = icmp sle i128 %x, %not
+ ret i1 %cmp
+}
+
+; X s>= X^Neg_C --> X s> -1
+define i1 @src_sge_allone(i8 %x) {
+; CHECK-LABEL: @src_sge_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -1
+ %cmp = icmp sge i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_sge_min(i8 %x) {
+; CHECK-LABEL: @src_sge_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -128
+ %cmp = icmp sge i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_sge_i128_allone(i128 %x) {
+; CHECK-LABEL: @src_sge_i128_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -1
+ %cmp = icmp sge i128 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_sge_i128_min(i128 %x) {
+; CHECK-LABEL: @src_sge_i128_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -170141183460469231731687303715884105728
+ %cmp = icmp sge i128 %x, %not
+ ret i1 %cmp
+}
+
+; X comp X^Neg_C tests, signed. commutative
+; Neg_C^X s< X --> X s> -1
+define i1 @src_slt_comm_allone(i8 %x) {
+; CHECK-LABEL: @src_slt_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -1, %x
+ %cmp = icmp slt i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_slt_comm_min(i8 %x) {
+; CHECK-LABEL: @src_slt_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -128, %x
+ %cmp = icmp slt i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_slt_i128_comm_allone(i128 %x) {
+; CHECK-LABEL: @src_slt_i128_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -1, %x
+ %cmp = icmp slt i128 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_slt_i128_comm_min(i128 %x) {
+; CHECK-LABEL: @src_slt_i128_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -170141183460469231731687303715884105728, %x
+ %cmp = icmp slt i128 %not, %x
+ ret i1 %cmp
+}
+
+; Neg_C^X s> X --> X s< 0
+define i1 @src_sgt_comm_allone(i8 %x) {
+; CHECK-LABEL: @src_sgt_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -1, %x
+ %cmp = icmp sgt i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_sgt_comm_min(i8 %x) {
+; CHECK-LABEL: @src_sgt_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -128, %x
+ %cmp = icmp sgt i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_sgt_i128_comm_allone(i128 %x) {
+; CHECK-LABEL: @src_sgt_i128_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -1, %x
+ %cmp = icmp sgt i128 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_sgt_i128_comm_min(i128 %x) {
+; CHECK-LABEL: @src_sgt_i128_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -170141183460469231731687303715884105728, %x
+ %cmp = icmp sgt i128 %not, %x
+ ret i1 %cmp
+}
+
+; X^Neg_C s<= X --> X s> -1
+define i1 @src_sle_comm_allone(i8 %x) {
+; CHECK-LABEL: @src_sle_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -1, %x
+ %cmp = icmp sle i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_sle_comm_min(i8 %x) {
+; CHECK-LABEL: @src_sle_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -128, %x
+ %cmp = icmp sle i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_sle_i128_comm_allone(i128 %x) {
+; CHECK-LABEL: @src_sle_i128_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -1, %x
+ %cmp = icmp sle i128 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_sle_i128_comm_min(i128 %x) {
+; CHECK-LABEL: @src_sle_i128_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -170141183460469231731687303715884105728, %x
+ %cmp = icmp sle i128 %not, %x
+ ret i1 %cmp
+}
+
+; Neg_C^X s>= X --> X s< 0
+define i1 @src_sge_comm_allone(i8 %x) {
+; CHECK-LABEL: @src_sge_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -1, %x
+ %cmp = icmp sge i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_sge_comm_min(i8 %x) {
+; CHECK-LABEL: @src_sge_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -128, %x
+ %cmp = icmp sge i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_sge_i128_comm_allone(i128 %x) {
+; CHECK-LABEL: @src_sge_i128_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -1, %x
+ %cmp = icmp sge i128 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_sge_i128_comm_min(i128 %x) {
+; CHECK-LABEL: @src_sge_i128_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -170141183460469231731687303715884105728, %x
+ %cmp = icmp sge i128 %not, %x
+ ret i1 %cmp
+}
+
+; X comp X^Neg_C tests, unsigned.
+; X u< X^Neg_C --> X s> -1
+define i1 @src_ult_allone(i8 %x) {
+; CHECK-LABEL: @src_ult_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -1
+ %cmp = icmp ult i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_ult_min(i8 %x) {
+; CHECK-LABEL: @src_ult_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -128
+ %cmp = icmp ult i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_ult_i128_allone(i128 %x) {
+; CHECK-LABEL: @src_ult_i128_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -1
+ %cmp = icmp ult i128 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_ult_i128_min(i128 %x) {
+; CHECK-LABEL: @src_ult_i128_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -170141183460469231731687303715884105728
+ %cmp = icmp ult i128 %x, %not
+ ret i1 %cmp
+}
+
+; X u> X^Neg_C --> X s< 0
+define i1 @src_ugt_allone(i8 %x) {
+; CHECK-LABEL: @src_ugt_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -1
+ %cmp = icmp ugt i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_ugt_min(i8 %x) {
+; CHECK-LABEL: @src_ugt_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -128
+ %cmp = icmp ugt i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_ugt_i128_allone(i128 %x) {
+; CHECK-LABEL: @src_ugt_i128_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -1
+ %cmp = icmp ugt i128 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_ugt_i128_min(i128 %x) {
+; CHECK-LABEL: @src_ugt_i128_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -170141183460469231731687303715884105728
+ %cmp = icmp ugt i128 %x, %not
+ ret i1 %cmp
+}
+
+; X u<= X^Neg_C --> X s> -1
+define i1 @src_ule_allone(i8 %x) {
+; CHECK-LABEL: @src_ule_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -1
+ %cmp = icmp ule i8 %x, %not
+ ret i1 %cmp
+}
+
+; X u<= X^Neg_C --> X s> -1
+define i1 @src_ule_min(i8 %x) {
+; CHECK-LABEL: @src_ule_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -128
+ %cmp = icmp ule i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_ule_i128_allone(i128 %x) {
+; CHECK-LABEL: @src_ule_i128_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -1
+ %cmp = icmp ule i128 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_ule_i128_min(i128 %x) {
+; CHECK-LABEL: @src_ule_i128_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -170141183460469231731687303715884105728
+ %cmp = icmp ule i128 %x, %not
+ ret i1 %cmp
+}
+
+; X u>= X^Neg_C --> X s< 0
+define i1 @src_uge_allone(i8 %x) {
+; CHECK-LABEL: @src_uge_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -1
+ %cmp = icmp uge i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_uge_min(i8 %x) {
+; CHECK-LABEL: @src_uge_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 %x, -128
+ %cmp = icmp uge i8 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_uge_i128_allone(i128 %x) {
+; CHECK-LABEL: @src_uge_i128_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -1
+ %cmp = icmp uge i128 %x, %not
+ ret i1 %cmp
+}
+
+define i1 @src_uge_i128_min(i128 %x) {
+; CHECK-LABEL: @src_uge_i128_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 %x, -170141183460469231731687303715884105728
+ %cmp = icmp uge i128 %x, %not
+ ret i1 %cmp
+}
+
+; X comp X^Neg_C tests, unsigned. commutative
+; Neg_C^X u< X --> X s< 0
+define i1 @src_ult_comm_allone(i8 %x) {
+; CHECK-LABEL: @src_ult_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -1, %x
+ %cmp = icmp ult i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_ult_comm_min(i8 %x) {
+; CHECK-LABEL: @src_ult_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -128, %x
+ %cmp = icmp ult i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_ult_i128_comm_allone(i128 %x) {
+; CHECK-LABEL: @src_ult_i128_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -1, %x
+ %cmp = icmp ult i128 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_ult_i128_comm_min(i128 %x) {
+; CHECK-LABEL: @src_ult_i128_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -170141183460469231731687303715884105728, %x
+ %cmp = icmp ult i128 %not, %x
+ ret i1 %cmp
+}
+
+; Neg_C^X u> X --> X s> -1
+define i1 @src_ugt_comm_allone(i8 %x) {
+; CHECK-LABEL: @src_ugt_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -1, %x
+ %cmp = icmp ugt i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_ugt_comm_min(i8 %x) {
+; CHECK-LABEL: @src_ugt_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -128, %x
+ %cmp = icmp ugt i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_ugt_i128_comm_allone(i128 %x) {
+; CHECK-LABEL: @src_ugt_i128_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -1, %x
+ %cmp = icmp ugt i128 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_ugt_i128_comm_min(i128 %x) {
+; CHECK-LABEL: @src_ugt_i128_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -170141183460469231731687303715884105728, %x
+ %cmp = icmp ugt i128 %not, %x
+ ret i1 %cmp
+}
+
+; Neg_C^X u<= X --> X s< 0
+define i1 @src_ule_comm_allone(i8 %x) {
+; CHECK-LABEL: @src_ule_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -1, %x
+ %cmp = icmp ule i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_ule_comm_min(i8 %x) {
+; CHECK-LABEL: @src_ule_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -128, %x
+ %cmp = icmp ule i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_ule_i128_comm_allone(i128 %x) {
+; CHECK-LABEL: @src_ule_i128_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -1, %x
+ %cmp = icmp ule i128 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_ule_i128_comm_min(i128 %x) {
+; CHECK-LABEL: @src_ule_i128_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -170141183460469231731687303715884105728, %x
+ %cmp = icmp ule i128 %not, %x
+ ret i1 %cmp
+}
+
+; Neg_C^X u>= X --> X s> -1
+define i1 @src_uge_comm_allone(i8 %x) {
+; CHECK-LABEL: @src_uge_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -1, %x
+ %cmp = icmp uge i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_uge_comm_min(i8 %x) {
+; CHECK-LABEL: @src_uge_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i8 -128, %x
+ %cmp = icmp uge i8 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_uge_i128_comm_allone(i128 %x) {
+; CHECK-LABEL: @src_uge_i128_comm_allone(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -1, %x
+ %cmp = icmp uge i128 %not, %x
+ ret i1 %cmp
+}
+
+define i1 @src_uge_i128_comm_min(i128 %x) {
+; CHECK-LABEL: @src_uge_i128_comm_min(
+; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %not = xor i128 -170141183460469231731687303715884105728, %x
+ %cmp = icmp uge i128 %not, %x
+ ret i1 %cmp
+}
+
+; X comp X^Neg_C tests. negative
+; X comp Y
+define i1 @src_sle_xny(i8 %x, i8 %y) {
+; CHECK-LABEL: @src_sle_xny(
+; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[Y_NOT]], [[X:%.*]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y.not = xor i8 %y, -1
+ %cmp = icmp sle i8 %x, %y.not
+ ret i1 %cmp
+}
+define i1 @src_sle_nyx(i8 %x, i8 %y) {
+; CHECK-LABEL: @src_sle_nyx(
+; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[Y_NOT]], [[X:%.*]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y.not = xor i8 %y, -1
+ %cmp = icmp sle i8 %y.not, %x
+ ret i1 %cmp
+}
+define i1 @src_sge_xny(i8 %x, i8 %y) {
+; CHECK-LABEL: @src_sge_xny(
+; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp sle i8 [[Y_NOT]], [[X:%.*]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y.not = xor i8 %y, -1
+ %cmp = icmp sge i8 %x, %y.not
+ ret i1 %cmp
+}
+define i1 @src_sge_nyx(i8 %x, i8 %y) {
+; CHECK-LABEL: @src_sge_nyx(
+; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[Y_NOT]], [[X:%.*]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y.not = xor i8 %y, -1
+ %cmp = icmp sge i8 %y.not, %x
+ ret i1 %cmp
+}
+define i1 @src_ule_xny(i8 %x, i8 %y) {
+; CHECK-LABEL: @src_ule_xny(
+; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[Y_NOT]], [[X:%.*]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y.not = xor i8 %y, -1
+ %cmp = icmp ule i8 %x, %y.not
+ ret i1 %cmp
+}
+define i1 @src_ule_nyx(i8 %x, i8 %y) {
+; CHECK-LABEL: @src_ule_nyx(
+; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[Y_NOT]], [[X:%.*]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y.not = xor i8 %y, -1
+ %cmp = icmp ule i8 %y.not, %x
+ ret i1 %cmp
+}
+define i1 @src_uge_xny(i8 %x, i8 %y) {
+; CHECK-LABEL: @src_uge_xny(
+; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[Y_NOT]], [[X:%.*]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y.not = xor i8 %y, -1
+ %cmp = icmp uge i8 %x, %y.not
+ ret i1 %cmp
+}
+define i1 @src_uge_nyx(i8 %x, i8 %y) {
+; CHECK-LABEL: @src_uge_nyx(
+; CHECK-NEXT: [[Y_NOT:%.*]] = xor i8 [[Y:%.*]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[Y_NOT]], [[X:%.*]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %y.not = xor i8 %y, -1
+ %cmp = icmp uge i8 %y.not, %x
+ ret i1 %cmp
+}
+
+; X comp X^Neg_C tests. negative
+; (X+1) comp X^Neg_C
+define i1 @src_sle_incx_nx(i8 %x) {
+; CHECK-LABEL: @src_sle_incx_nx(
+; CHECK-NEXT: [[TMP1:%.*]] = sub i8 -2, [[X:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[TMP1]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %nx = xor i8 %x, -1
+ %inc.x = add i8 %x, 1
+ %cmp = icmp sle i8 %inc.x, %nx
+ ret i1 %cmp
+}
+; (X-1) comp X^Neg_C
+define i1 @src_sle_decx_nx(i8 %x) {
+; CHECK-LABEL: @src_sle_decx_nx(
+; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[X:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[TMP1]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %nx = xor i8 %x, -1
+ %dec.x = add i8 %x, -1
+ %cmp = icmp sle i8 %dec.x, %nx
+ ret i1 %cmp
+}
+; X comp (X+1)^Neg_C
+define i1 @src_sle_x_nincx(i8 %x) {
+; CHECK-LABEL: @src_sle_x_nincx(
+; CHECK-NEXT: [[NOT_INC_X:%.*]] = sub i8 -2, [[X:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[NOT_INC_X]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %inc.x = add i8 %x, 1
+ %not.inc.x = xor i8 %inc.x, -1
+ %cmp = icmp sle i8 %x, %not.inc.x
+ ret i1 %cmp
+}
+; X comp (X-1)^Neg_C
+define i1 @src_sle_x_ndecx(i8 %x) {
+; CHECK-LABEL: @src_sle_x_ndecx(
+; CHECK-NEXT: [[NOT_DEC_X:%.*]] = sub i8 0, [[X:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sge i8 [[NOT_DEC_X]], [[X]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %dec.x = add i8 %x, -1
+ %not.dec.x = xor i8 %dec.x, -1
+ %cmp = icmp sle i8 %x, %not.dec.x
+ ret i1 %cmp
+}
+
+; X comp X^Neg_C vector tests
+; X s< X^Neg_C --> X s< 0
+define <2 x i1> @src_slt_xnx_to_slt_0_i8_vec(<2 x i8> %x) {
+; CHECK-LABEL: @src_slt_xnx_to_slt_0_i8_vec(
+; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[NOT]], [[X]]
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %not = xor <2 x i8> %x, <i8 -1, i8 -1>
+ %cmp = icmp slt <2 x i8> %x, %not
+ ret <2 x i1> %cmp
+}
+; X s> X^Neg_C --> X s> -1
+define <2 x i1> @src_sgt_xnx_to_sgt_n1_i8_vec(<2 x i8> %x) {
+; CHECK-LABEL: @src_sgt_xnx_to_sgt_n1_i8_vec(
+; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[NOT]], [[X]]
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %not = xor <2 x i8> %x, <i8 -1, i8 -1>
+ %cmp = icmp sgt <2 x i8> %x, %not
+ ret <2 x i1> %cmp
+}
+; X s<= X^Neg_C --> X s< X^Neg_C --> X s< 0
+define <2 x i1> @src_sle_xnx_to_slt_0_i8_vec(<2 x i8> %x) {
+; CHECK-LABEL: @src_sle_xnx_to_slt_0_i8_vec(
+; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[NOT]], [[X]]
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %not = xor <2 x i8> %x, <i8 -1, i8 -1>
+ %cmp = icmp sle <2 x i8> %x, %not
+ ret <2 x i1> %cmp
+}
+; X s>= X^Neg_C --> X s> X^Neg_C --> X s> -1
+define <2 x i1> @src_sge_xnx_to_sgt_n1_i8_vec(<2 x i8> %x) {
+; CHECK-LABEL: @src_sge_xnx_to_sgt_n1_i8_vec(
+; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[NOT]], [[X]]
+; CHECK-NEXT: ret <2 x i1> [[CMP]]
+;
+ %not = xor <2 x i8> %x, <i8 -1, i8 -1>
+ %cmp = icmp sge <2 x i8> %x, %not
+ ret <2 x i1> %cmp
+}
+
; test for (~x ^ y) < ~z
define i1 @test_xor1(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @test_xor1(
>From 1e6dd6f1da6f5309a51260bf9b5e4d96ae413b64 Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Fri, 1 Dec 2023 06:32:35 +0900
Subject: [PATCH 2/2] [InstCombine] simplify `X (comp) X^Neg_C` (#57532)
This patch simplifies the comparison between X and X^Neg_X.
comparison between X and X^Neg_C is determined solely by
presence of the sign bit, so we can simplify it to checking
whether X is negative or not.
Proof: https://alive2.llvm.org/ce/z/-wrKSp
---
.../InstCombine/InstCombineCompares.cpp | 26 +++
.../Transforms/InstCombine/icmp-of-xor-x.ll | 204 ++++++------------
2 files changed, 94 insertions(+), 136 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 280c4d77b6dfca..d326cf81b09583 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -4605,6 +4605,30 @@ static Instruction *foldICmpXorXX(ICmpInst &I, const SimplifyQuery &Q,
isKnownNonZero(A, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT))
return new ICmpInst(PredOut, Op0, Op1);
+ // These transform works when C is negative.
+ // X s< X^C, X s<= X^C, X u> X^C, X u>= X^C --> X s< 0
+ // X s> X^C, X s>= X^C, X u< X^C, X u<= X^C --> X s>= 0
+ if (auto C = dyn_cast<Constant>(A)) {
+ if (!C->getUniqueInteger().isNegative())
+ return nullptr;
+
+ CmpInst::Predicate NewPred;
+ switch (ICmpInst::getStrictPredicate(Pred)) {
+ default:
+ llvm_unreachable("not a valid predicate");
+ case ICmpInst::ICMP_SLT:
+ case ICmpInst::ICMP_UGT:
+ NewPred = ICmpInst::ICMP_SLT;
+ break;
+ case ICmpInst::ICMP_SGT:
+ case ICmpInst::ICMP_ULT:
+ NewPred = ICmpInst::ICMP_SGE;
+ break;
+ }
+ Constant *Const = Constant::getNullValue(Op0->getType());
+ return new ICmpInst(NewPred, Op0, Const);
+ }
+
return nullptr;
}
@@ -7190,6 +7214,8 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
}
}
+
+
Instruction *AddI = nullptr;
if (match(&I, m_UAddWithOverflow(m_Value(X), m_Value(Y),
m_Instruction(AddI))) &&
diff --git a/llvm/test/Transforms/InstCombine/icmp-of-xor-x.ll b/llvm/test/Transforms/InstCombine/icmp-of-xor-x.ll
index 96ef7ce727d9cd..78c491af69646a 100644
--- a/llvm/test/Transforms/InstCombine/icmp-of-xor-x.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-of-xor-x.ll
@@ -9,8 +9,7 @@ declare void @use.i8(i8)
; X s< X^Neg_C --> X s< 0
define i1 @src_slt_allone(i8 %x) {
; CHECK-LABEL: @src_slt_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -1
@@ -20,8 +19,7 @@ define i1 @src_slt_allone(i8 %x) {
define i1 @src_slt_min(i8 %x) {
; CHECK-LABEL: @src_slt_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -128
@@ -31,8 +29,7 @@ define i1 @src_slt_min(i8 %x) {
define i1 @src_slt_i128_allone(i128 %x) {
; CHECK-LABEL: @src_slt_i128_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -1
@@ -42,8 +39,7 @@ define i1 @src_slt_i128_allone(i128 %x) {
define i1 @src_slt_i128_min(i128 %x) {
; CHECK-LABEL: @src_slt_i128_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -170141183460469231731687303715884105728
@@ -54,8 +50,7 @@ define i1 @src_slt_i128_min(i128 %x) {
; X s> X^Neg_C --> X s> -1
define i1 @src_sgt_allone(i8 %x) {
; CHECK-LABEL: @src_sgt_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -1
@@ -65,8 +60,7 @@ define i1 @src_sgt_allone(i8 %x) {
define i1 @src_sgt_min(i8 %x) {
; CHECK-LABEL: @src_sgt_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -128
@@ -76,8 +70,7 @@ define i1 @src_sgt_min(i8 %x) {
define i1 @src_sgt_i128_allone(i128 %x) {
; CHECK-LABEL: @src_sgt_i128_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -1
@@ -87,8 +80,7 @@ define i1 @src_sgt_i128_allone(i128 %x) {
define i1 @src_sgt_i128_min(i128 %x) {
; CHECK-LABEL: @src_sgt_i128_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -170141183460469231731687303715884105728
@@ -99,8 +91,7 @@ define i1 @src_sgt_i128_min(i128 %x) {
; X s<= X^Neg_C --> X s< 0
define i1 @src_sle_allone(i8 %x) {
; CHECK-LABEL: @src_sle_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -1
@@ -110,8 +101,7 @@ define i1 @src_sle_allone(i8 %x) {
define i1 @src_sle_min(i8 %x) {
; CHECK-LABEL: @src_sle_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -128
@@ -121,8 +111,7 @@ define i1 @src_sle_min(i8 %x) {
define i1 @src_sle_i128_allone(i128 %x) {
; CHECK-LABEL: @src_sle_i128_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -1
@@ -132,8 +121,7 @@ define i1 @src_sle_i128_allone(i128 %x) {
define i1 @src_sle_i128_min(i128 %x) {
; CHECK-LABEL: @src_sle_i128_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -170141183460469231731687303715884105728
@@ -144,8 +132,7 @@ define i1 @src_sle_i128_min(i128 %x) {
; X s>= X^Neg_C --> X s> -1
define i1 @src_sge_allone(i8 %x) {
; CHECK-LABEL: @src_sge_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -1
@@ -155,8 +142,7 @@ define i1 @src_sge_allone(i8 %x) {
define i1 @src_sge_min(i8 %x) {
; CHECK-LABEL: @src_sge_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -128
@@ -166,8 +152,7 @@ define i1 @src_sge_min(i8 %x) {
define i1 @src_sge_i128_allone(i128 %x) {
; CHECK-LABEL: @src_sge_i128_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -1
@@ -177,8 +162,7 @@ define i1 @src_sge_i128_allone(i128 %x) {
define i1 @src_sge_i128_min(i128 %x) {
; CHECK-LABEL: @src_sge_i128_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -170141183460469231731687303715884105728
@@ -190,8 +174,7 @@ define i1 @src_sge_i128_min(i128 %x) {
; Neg_C^X s< X --> X s> -1
define i1 @src_slt_comm_allone(i8 %x) {
; CHECK-LABEL: @src_slt_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -1, %x
@@ -201,8 +184,7 @@ define i1 @src_slt_comm_allone(i8 %x) {
define i1 @src_slt_comm_min(i8 %x) {
; CHECK-LABEL: @src_slt_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -128, %x
@@ -212,8 +194,7 @@ define i1 @src_slt_comm_min(i8 %x) {
define i1 @src_slt_i128_comm_allone(i128 %x) {
; CHECK-LABEL: @src_slt_i128_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -1, %x
@@ -223,8 +204,7 @@ define i1 @src_slt_i128_comm_allone(i128 %x) {
define i1 @src_slt_i128_comm_min(i128 %x) {
; CHECK-LABEL: @src_slt_i128_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -170141183460469231731687303715884105728, %x
@@ -235,8 +215,7 @@ define i1 @src_slt_i128_comm_min(i128 %x) {
; Neg_C^X s> X --> X s< 0
define i1 @src_sgt_comm_allone(i8 %x) {
; CHECK-LABEL: @src_sgt_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -1, %x
@@ -246,8 +225,7 @@ define i1 @src_sgt_comm_allone(i8 %x) {
define i1 @src_sgt_comm_min(i8 %x) {
; CHECK-LABEL: @src_sgt_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -128, %x
@@ -257,8 +235,7 @@ define i1 @src_sgt_comm_min(i8 %x) {
define i1 @src_sgt_i128_comm_allone(i128 %x) {
; CHECK-LABEL: @src_sgt_i128_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -1, %x
@@ -268,8 +245,7 @@ define i1 @src_sgt_i128_comm_allone(i128 %x) {
define i1 @src_sgt_i128_comm_min(i128 %x) {
; CHECK-LABEL: @src_sgt_i128_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -170141183460469231731687303715884105728, %x
@@ -280,8 +256,7 @@ define i1 @src_sgt_i128_comm_min(i128 %x) {
; X^Neg_C s<= X --> X s> -1
define i1 @src_sle_comm_allone(i8 %x) {
; CHECK-LABEL: @src_sle_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -1, %x
@@ -291,8 +266,7 @@ define i1 @src_sle_comm_allone(i8 %x) {
define i1 @src_sle_comm_min(i8 %x) {
; CHECK-LABEL: @src_sle_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -128, %x
@@ -302,8 +276,7 @@ define i1 @src_sle_comm_min(i8 %x) {
define i1 @src_sle_i128_comm_allone(i128 %x) {
; CHECK-LABEL: @src_sle_i128_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -1, %x
@@ -313,8 +286,7 @@ define i1 @src_sle_i128_comm_allone(i128 %x) {
define i1 @src_sle_i128_comm_min(i128 %x) {
; CHECK-LABEL: @src_sle_i128_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -170141183460469231731687303715884105728, %x
@@ -325,8 +297,7 @@ define i1 @src_sle_i128_comm_min(i128 %x) {
; Neg_C^X s>= X --> X s< 0
define i1 @src_sge_comm_allone(i8 %x) {
; CHECK-LABEL: @src_sge_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -1, %x
@@ -336,8 +307,7 @@ define i1 @src_sge_comm_allone(i8 %x) {
define i1 @src_sge_comm_min(i8 %x) {
; CHECK-LABEL: @src_sge_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -128, %x
@@ -347,8 +317,7 @@ define i1 @src_sge_comm_min(i8 %x) {
define i1 @src_sge_i128_comm_allone(i128 %x) {
; CHECK-LABEL: @src_sge_i128_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -1, %x
@@ -358,8 +327,7 @@ define i1 @src_sge_i128_comm_allone(i128 %x) {
define i1 @src_sge_i128_comm_min(i128 %x) {
; CHECK-LABEL: @src_sge_i128_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -170141183460469231731687303715884105728, %x
@@ -371,8 +339,7 @@ define i1 @src_sge_i128_comm_min(i128 %x) {
; X u< X^Neg_C --> X s> -1
define i1 @src_ult_allone(i8 %x) {
; CHECK-LABEL: @src_ult_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -1
@@ -382,8 +349,7 @@ define i1 @src_ult_allone(i8 %x) {
define i1 @src_ult_min(i8 %x) {
; CHECK-LABEL: @src_ult_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -128
@@ -393,8 +359,7 @@ define i1 @src_ult_min(i8 %x) {
define i1 @src_ult_i128_allone(i128 %x) {
; CHECK-LABEL: @src_ult_i128_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -1
@@ -404,8 +369,7 @@ define i1 @src_ult_i128_allone(i128 %x) {
define i1 @src_ult_i128_min(i128 %x) {
; CHECK-LABEL: @src_ult_i128_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -170141183460469231731687303715884105728
@@ -416,8 +380,7 @@ define i1 @src_ult_i128_min(i128 %x) {
; X u> X^Neg_C --> X s< 0
define i1 @src_ugt_allone(i8 %x) {
; CHECK-LABEL: @src_ugt_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -1
@@ -427,8 +390,7 @@ define i1 @src_ugt_allone(i8 %x) {
define i1 @src_ugt_min(i8 %x) {
; CHECK-LABEL: @src_ugt_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -128
@@ -438,8 +400,7 @@ define i1 @src_ugt_min(i8 %x) {
define i1 @src_ugt_i128_allone(i128 %x) {
; CHECK-LABEL: @src_ugt_i128_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -1
@@ -449,8 +410,7 @@ define i1 @src_ugt_i128_allone(i128 %x) {
define i1 @src_ugt_i128_min(i128 %x) {
; CHECK-LABEL: @src_ugt_i128_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -170141183460469231731687303715884105728
@@ -461,8 +421,7 @@ define i1 @src_ugt_i128_min(i128 %x) {
; X u<= X^Neg_C --> X s> -1
define i1 @src_ule_allone(i8 %x) {
; CHECK-LABEL: @src_ule_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -1
@@ -473,8 +432,7 @@ define i1 @src_ule_allone(i8 %x) {
; X u<= X^Neg_C --> X s> -1
define i1 @src_ule_min(i8 %x) {
; CHECK-LABEL: @src_ule_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -128
@@ -484,8 +442,7 @@ define i1 @src_ule_min(i8 %x) {
define i1 @src_ule_i128_allone(i128 %x) {
; CHECK-LABEL: @src_ule_i128_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -1
@@ -495,8 +452,7 @@ define i1 @src_ule_i128_allone(i128 %x) {
define i1 @src_ule_i128_min(i128 %x) {
; CHECK-LABEL: @src_ule_i128_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -170141183460469231731687303715884105728
@@ -507,8 +463,7 @@ define i1 @src_ule_i128_min(i128 %x) {
; X u>= X^Neg_C --> X s< 0
define i1 @src_uge_allone(i8 %x) {
; CHECK-LABEL: @src_uge_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -1
@@ -518,8 +473,7 @@ define i1 @src_uge_allone(i8 %x) {
define i1 @src_uge_min(i8 %x) {
; CHECK-LABEL: @src_uge_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 %x, -128
@@ -529,8 +483,7 @@ define i1 @src_uge_min(i8 %x) {
define i1 @src_uge_i128_allone(i128 %x) {
; CHECK-LABEL: @src_uge_i128_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -1
@@ -540,8 +493,7 @@ define i1 @src_uge_i128_allone(i128 %x) {
define i1 @src_uge_i128_min(i128 %x) {
; CHECK-LABEL: @src_uge_i128_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 %x, -170141183460469231731687303715884105728
@@ -553,8 +505,7 @@ define i1 @src_uge_i128_min(i128 %x) {
; Neg_C^X u< X --> X s< 0
define i1 @src_ult_comm_allone(i8 %x) {
; CHECK-LABEL: @src_ult_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -1, %x
@@ -564,8 +515,7 @@ define i1 @src_ult_comm_allone(i8 %x) {
define i1 @src_ult_comm_min(i8 %x) {
; CHECK-LABEL: @src_ult_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -128, %x
@@ -575,8 +525,7 @@ define i1 @src_ult_comm_min(i8 %x) {
define i1 @src_ult_i128_comm_allone(i128 %x) {
; CHECK-LABEL: @src_ult_i128_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -1, %x
@@ -586,8 +535,7 @@ define i1 @src_ult_i128_comm_allone(i128 %x) {
define i1 @src_ult_i128_comm_min(i128 %x) {
; CHECK-LABEL: @src_ult_i128_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -170141183460469231731687303715884105728, %x
@@ -598,8 +546,7 @@ define i1 @src_ult_i128_comm_min(i128 %x) {
; Neg_C^X u> X --> X s> -1
define i1 @src_ugt_comm_allone(i8 %x) {
; CHECK-LABEL: @src_ugt_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -1, %x
@@ -609,8 +556,7 @@ define i1 @src_ugt_comm_allone(i8 %x) {
define i1 @src_ugt_comm_min(i8 %x) {
; CHECK-LABEL: @src_ugt_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -128, %x
@@ -620,8 +566,7 @@ define i1 @src_ugt_comm_min(i8 %x) {
define i1 @src_ugt_i128_comm_allone(i128 %x) {
; CHECK-LABEL: @src_ugt_i128_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -1, %x
@@ -631,8 +576,7 @@ define i1 @src_ugt_i128_comm_allone(i128 %x) {
define i1 @src_ugt_i128_comm_min(i128 %x) {
; CHECK-LABEL: @src_ugt_i128_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -170141183460469231731687303715884105728, %x
@@ -643,8 +587,7 @@ define i1 @src_ugt_i128_comm_min(i128 %x) {
; Neg_C^X u<= X --> X s< 0
define i1 @src_ule_comm_allone(i8 %x) {
; CHECK-LABEL: @src_ule_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -1, %x
@@ -654,8 +597,7 @@ define i1 @src_ule_comm_allone(i8 %x) {
define i1 @src_ule_comm_min(i8 %x) {
; CHECK-LABEL: @src_ule_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -128, %x
@@ -665,8 +607,7 @@ define i1 @src_ule_comm_min(i8 %x) {
define i1 @src_ule_i128_comm_allone(i128 %x) {
; CHECK-LABEL: @src_ule_i128_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -1, %x
@@ -676,8 +617,7 @@ define i1 @src_ule_i128_comm_allone(i128 %x) {
define i1 @src_ule_i128_comm_min(i128 %x) {
; CHECK-LABEL: @src_ule_i128_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -170141183460469231731687303715884105728, %x
@@ -688,8 +628,7 @@ define i1 @src_ule_i128_comm_min(i128 %x) {
; Neg_C^X u>= X --> X s> -1
define i1 @src_uge_comm_allone(i8 %x) {
; CHECK-LABEL: @src_uge_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -1, %x
@@ -699,8 +638,7 @@ define i1 @src_uge_comm_allone(i8 %x) {
define i1 @src_uge_comm_min(i8 %x) {
; CHECK-LABEL: @src_uge_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[X:%.*]], -128
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i8 -128, %x
@@ -710,8 +648,7 @@ define i1 @src_uge_comm_min(i8 %x) {
define i1 @src_uge_i128_comm_allone(i128 %x) {
; CHECK-LABEL: @src_uge_i128_comm_allone(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -1, %x
@@ -721,8 +658,7 @@ define i1 @src_uge_i128_comm_allone(i128 %x) {
define i1 @src_uge_i128_comm_min(i128 %x) {
; CHECK-LABEL: @src_uge_i128_comm_min(
-; CHECK-NEXT: [[NOT:%.*]] = xor i128 [[X:%.*]], -170141183460469231731687303715884105728
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%not = xor i128 -170141183460469231731687303715884105728, %x
@@ -867,8 +803,7 @@ define i1 @src_sle_x_ndecx(i8 %x) {
; X s< X^Neg_C --> X s< 0
define <2 x i1> @src_slt_xnx_to_slt_0_i8_vec(<2 x i8> %x) {
; CHECK-LABEL: @src_slt_xnx_to_slt_0_i8_vec(
-; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%not = xor <2 x i8> %x, <i8 -1, i8 -1>
@@ -878,8 +813,7 @@ define <2 x i1> @src_slt_xnx_to_slt_0_i8_vec(<2 x i8> %x) {
; X s> X^Neg_C --> X s> -1
define <2 x i1> @src_sgt_xnx_to_sgt_n1_i8_vec(<2 x i8> %x) {
; CHECK-LABEL: @src_sgt_xnx_to_sgt_n1_i8_vec(
-; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%not = xor <2 x i8> %x, <i8 -1, i8 -1>
@@ -889,8 +823,7 @@ define <2 x i1> @src_sgt_xnx_to_sgt_n1_i8_vec(<2 x i8> %x) {
; X s<= X^Neg_C --> X s< X^Neg_C --> X s< 0
define <2 x i1> @src_sle_xnx_to_slt_0_i8_vec(<2 x i8> %x) {
; CHECK-LABEL: @src_sle_xnx_to_slt_0_i8_vec(
-; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[X:%.*]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%not = xor <2 x i8> %x, <i8 -1, i8 -1>
@@ -900,8 +833,7 @@ define <2 x i1> @src_sle_xnx_to_slt_0_i8_vec(<2 x i8> %x) {
; X s>= X^Neg_C --> X s> X^Neg_C --> X s> -1
define <2 x i1> @src_sge_xnx_to_sgt_n1_i8_vec(<2 x i8> %x) {
; CHECK-LABEL: @src_sge_xnx_to_sgt_n1_i8_vec(
-; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[NOT]], [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%not = xor <2 x i8> %x, <i8 -1, i8 -1>
More information about the llvm-commits
mailing list