[llvm] [clang] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
LĂ©onard Oest O'Leary via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 1 13:02:57 PDT 2023
https://github.com/leo-ard updated https://github.com/llvm/llvm-project/pull/70845
>From 6bb97fd48d59b7f79fdf90a2b27e9220f417fac7 Mon Sep 17 00:00:00 2001
From: leo-ard <lool4516 at gmail.com>
Date: Mon, 30 Oct 2023 18:01:27 -0400
Subject: [PATCH 1/9] Add NonNeg check for InstCombine
---
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 7574987d0e23141..4751d870da7a777 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -5587,11 +5587,15 @@ Instruction *InstCombinerImpl::foldICmpWithZextOrSext(ICmpInst &ICmp) {
return new ICmpInst(ICmp.getPredicate(), Builder.CreateOr(X, Y),
Constant::getNullValue(X->getType()));
+ // Treat "zext nneg" as "sext"
+ bool IsNonNeg0 = isa<PossiblyNonNegInst>(ICmp.getOperand(0));
+ bool IsNonNeg1 = isa<PossiblyNonNegInst>(ICmp.getOperand(1));
+
// If we have mismatched casts, treat the zext of a non-negative source as
// a sext to simulate matching casts. Otherwise, we are done.
// TODO: Can we handle some predicates (equality) without non-negative?
- if ((IsZext0 && isKnownNonNegative(X, DL, 0, &AC, &ICmp, &DT)) ||
- (IsZext1 && isKnownNonNegative(Y, DL, 0, &AC, &ICmp, &DT)))
+ if ((IsZext0 && (IsNonNeg0 || isKnownNonNegative(X, DL, 0, &AC, &ICmp, &DT))) ||
+ (IsZext1 && (IsNonNeg1 || isKnownNonNegative(Y, DL, 0, &AC, &ICmp, &DT))))
IsSignedExt = true;
else
return nullptr;
>From 6570c0a864805408928a0d7a54dd0098f2d58419 Mon Sep 17 00:00:00 2001
From: leo-ard <lool4516 at gmail.com>
Date: Mon, 30 Oct 2023 18:03:44 -0400
Subject: [PATCH 2/9] Add tests for min/max
---
clang/test/CodeGen/X86/min_max.c | 19 ++
.../Transforms/SCCP/icmp-fold-with-cast.ll | 185 ++++++++++++++++++
2 files changed, 204 insertions(+)
create mode 100644 clang/test/CodeGen/X86/min_max.c
create mode 100644 llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll
diff --git a/clang/test/CodeGen/X86/min_max.c b/clang/test/CodeGen/X86/min_max.c
new file mode 100644
index 000000000000000..7af8181cc9ff367
--- /dev/null
+++ b/clang/test/CodeGen/X86/min_max.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -O2 -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+
+short vecreduce_smax_v2i16(int n, short* v)
+{
+ // CHECK: @llvm.smax
+ short p = 0;
+ for (int i = 0; i < n; ++i)
+ p = p < v[i] ? v[i] : p;
+ return p;
+}
+
+short vecreduce_smin_v2i16(int n, short* v)
+{
+ // CHECK: @llvm.smin
+ short p = 0;
+ for (int i = 0; i < n; ++i)
+ p = p > v[i] ? v[i] : p;
+ return p;
+}
\ No newline at end of file
diff --git a/llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll b/llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll
new file mode 100644
index 000000000000000..90b2c123081fb49
--- /dev/null
+++ b/llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll
@@ -0,0 +1,185 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --tool ./bin/opt --version 3
+; See PRXXX for more details
+; RUN: opt < %s -S -passes=ipsccp | FileCheck %s
+
+
+define signext i32 @sext_sext(i16 %x, i16 %y) {
+; CHECK-LABEL: define signext i32 @sext_sext(
+; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[X]] to i32
+; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[Y]] to i32
+; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i16 [[X]], [[Y]]
+; CHECK-NEXT: br i1 [[CMP2]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+; CHECK: cond.true:
+; CHECK-NEXT: br label [[COND_END:%.*]]
+; CHECK: cond.false:
+; CHECK-NEXT: br label [[COND_END]]
+; CHECK: cond.end:
+; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[COND_TRUE]] ], [ 1, [[COND_FALSE]] ]
+; CHECK-NEXT: ret i32 [[COND]]
+;
+entry:
+ %conv = sext i16 %x to i32
+ %conv1 = sext i16 %y to i32
+ %cmp2 = icmp sgt i32 %conv, %conv1
+ br i1 %cmp2, label %cond.true, label %cond.false
+
+cond.true: ; preds = %for.body
+ br label %cond.end
+
+cond.false: ; preds = %for.body
+ br label %cond.end
+
+cond.end: ; preds = %cond.false, %cond.true
+ %cond = phi i32 [ 0, %cond.true ], [ 1, %cond.false ]
+ ret i32 %cond
+}
+
+
+define signext i32 @zext_zext(i16 %x, i16 %y) {
+; CHECK-LABEL: define signext i32 @zext_zext(
+; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[X]] to i32
+; CHECK-NEXT: [[CONV1:%.*]] = zext i16 [[Y]] to i32
+; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i16 [[X]], [[Y]]
+; CHECK-NEXT: br i1 [[CMP2]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+; CHECK: cond.true:
+; CHECK-NEXT: br label [[COND_END:%.*]]
+; CHECK: cond.false:
+; CHECK-NEXT: br label [[COND_END]]
+; CHECK: cond.end:
+; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[COND_TRUE]] ], [ 1, [[COND_FALSE]] ]
+; CHECK-NEXT: ret i32 [[COND]]
+;
+entry:
+ %conv = zext i16 %x to i32
+ %conv1 = zext i16 %y to i32
+ %cmp2 = icmp sgt i32 %conv, %conv1
+ br i1 %cmp2, label %cond.true, label %cond.false
+
+cond.true: ; preds = %for.body
+ br label %cond.end
+
+cond.false: ; preds = %for.body
+ br label %cond.end
+
+cond.end: ; preds = %cond.false, %cond.true
+ %cond = phi i32 [ 0, %cond.true ], [ 1, %cond.false ]
+ ret i32 %cond
+}
+
+
+define signext i16 @zext_positive_and_sext(i32 noundef %n, ptr noundef %v) {
+; CHECK-LABEL: define signext i16 @zext_positive_and_sext(
+; CHECK-SAME: i32 noundef [[N:%.*]], ptr noundef [[V:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[FOR_COND:%.*]]
+; CHECK: for.cond:
+; CHECK-NEXT: [[P_0:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[CONV8:%.*]], [[COND_END:%.*]] ]
+; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[COND_END]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N]]
+; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
+; CHECK: for.body:
+; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[P_0]] to i32
+; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[I_0]] to i64
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr i16, ptr [[V]], i64 [[IDXPROM]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[ARRAYIDX]], align 2
+; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[TMP0]] to i32
+; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i16 [[P_0]], [[TMP0]]
+; CHECK-NEXT: br i1 [[CMP2]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+; CHECK: cond.true:
+; CHECK-NEXT: br label [[COND_END]]
+; CHECK: cond.false:
+; CHECK-NEXT: br label [[COND_END]]
+; CHECK: for.cond.cleanup:
+; CHECK-NEXT: ret i16 [[P_0]]
+; CHECK: cond.end:
+; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[CONV1]], [[COND_TRUE]] ], [ [[CONV]], [[COND_FALSE]] ]
+; CHECK-NEXT: [[CONV8]] = trunc i32 [[COND]] to i16
+; CHECK-NEXT: [[INC]] = add nsw i32 [[I_0]], 1
+; CHECK-NEXT: br label [[FOR_COND]]
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %cond.end, %entry
+ %p.0 = phi i16 [ 0, %entry ], [ %conv8, %cond.end ]
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %cond.end ]
+ %cmp = icmp slt i32 %i.0, %n
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.body: ; preds = %for.cond
+ %conv = zext i16 %p.0 to i32 ;; %p.0 is always positive here
+ %idxprom = sext i32 %i.0 to i64
+ %arrayidx = getelementptr i16, ptr %v, i64 %idxprom
+ %0 = load i16, ptr %arrayidx, align 2
+ %conv1 = sext i16 %0 to i32
+ %cmp2 = icmp slt i32 %conv, %conv1
+ br i1 %cmp2, label %cond.true, label %cond.false
+
+cond.true: ; preds = %for.body
+ br label %cond.end
+
+cond.false: ; preds = %for.body
+ br label %cond.end
+
+for.cond.cleanup: ; preds = %for.cond
+ ret i16 %p.0
+
+cond.end: ; preds = %cond.false, %cond.true
+ %cond = phi i32 [ %conv1, %cond.true ], [ %conv, %cond.false ]
+ %conv8 = trunc i32 %cond to i16
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+}
+
+
+
+define signext i16 @sext_and_zext_positive(i16 %x) {
+; CHECK-LABEL: define signext i16 @sext_and_zext_positive(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[FOR_COND:%.*]]
+; CHECK: for.cond:
+; CHECK-NEXT: [[V:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[COND_END:%.*]] ]
+; CHECK-NEXT: br label [[FOR_BODY:%.*]]
+; CHECK: for.body:
+; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[V]] to i32
+; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[X]] to i32
+; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i16 [[X]], [[V]]
+; CHECK-NEXT: br i1 [[CMP2]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+; CHECK: cond.true:
+; CHECK-NEXT: br label [[COND_END]]
+; CHECK: cond.false:
+; CHECK-NEXT: br label [[COND_END]]
+; CHECK: cond.end:
+; CHECK-NEXT: [[A:%.*]] = phi i16 [ 10, [[COND_TRUE]] ], [ 20, [[COND_FALSE]] ]
+; CHECK-NEXT: [[INC]] = add nuw nsw i16 [[A]], 1
+; CHECK-NEXT: br label [[FOR_COND]]
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %cond.end, %entry
+ %v = phi i16 [ 0, %entry ], [ %inc, %cond.end ] ;; always positive
+ br label %for.body
+
+for.body: ; preds = %for.cond
+ %conv = zext i16 %v to i32 ;; %p.0 is always positive here
+ %conv1 = sext i16 %x to i32 ;; %p.0 is always positive here
+ %cmp2 = icmp slt i32 %conv1, %conv ;; positive/positive
+ br i1 %cmp2, label %cond.true, label %cond.false
+
+cond.true: ; preds = %for.body
+ br label %cond.end
+
+cond.false: ; preds = %for.body
+ br label %cond.end
+
+cond.end: ; preds = %cond.false, %cond.true
+ %a = phi i16 [ 10, %cond.true ], [ 20, %cond.false ]
+ %inc = add i16 %a, 1
+ br label %for.cond
+}
>From d166c4f01d83260c50c07e084cd516956ddac785 Mon Sep 17 00:00:00 2001
From: leo-ard <lool4516 at gmail.com>
Date: Tue, 31 Oct 2023 13:24:49 -0400
Subject: [PATCH 3/9] Regenerate tests
---
...004-11-27-SetCCForCastLargerAndConstant.ll | 5 +-
.../Transforms/InstCombine/icmp-ext-ext.ll | 49 ++++++-------------
.../Transforms/SCCP/icmp-fold-with-cast.ll | 2 +-
3 files changed, 19 insertions(+), 37 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll b/llvm/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll
index 2e70a95dfde6233..b24a71b8dc15ea6 100644
--- a/llvm/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll
+++ b/llvm/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll
@@ -403,9 +403,8 @@ define i1 @different_size_sext_sext_ule(i7 %x, i4 %y) {
define i1 @different_size_sext_zext_ne(i7 %x, i4 %y) {
; CHECK-LABEL: @different_size_sext_zext_ne(
-; CHECK-NEXT: [[SX:%.*]] = sext i7 [[X:%.*]] to i25
-; CHECK-NEXT: [[ZY:%.*]] = zext i4 [[Y:%.*]] to i25
-; CHECK-NEXT: [[R:%.*]] = icmp ne i25 [[SX]], [[ZY]]
+; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y:%.*]] to i7
+; CHECK-NEXT: [[R:%.*]] = icmp ne i7 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%sx = sext i7 %x to i25
diff --git a/llvm/test/Transforms/InstCombine/icmp-ext-ext.ll b/llvm/test/Transforms/InstCombine/icmp-ext-ext.ll
index f70e48e27384619..87532c1faff1526 100644
--- a/llvm/test/Transforms/InstCombine/icmp-ext-ext.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-ext-ext.ll
@@ -119,9 +119,7 @@ define <2 x i1> @sext_sext_uge_op0_wide(<2 x i16> %x, <2 x i8> %y) {
define i1 @zext_sext_sgt(i8 %x, i8 %y) {
; CHECK-LABEL: @zext_sext_sgt(
-; CHECK-NEXT: [[A:%.*]] = zext i8 [[X:%.*]] to i32
-; CHECK-NEXT: [[B:%.*]] = sext i8 [[Y:%.*]] to i32
-; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], [[B]]
+; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = zext i8 %x to i32
@@ -132,9 +130,7 @@ define i1 @zext_sext_sgt(i8 %x, i8 %y) {
define i1 @zext_sext_ugt(i8 %x, i8 %y) {
; CHECK-LABEL: @zext_sext_ugt(
-; CHECK-NEXT: [[A:%.*]] = zext i8 [[X:%.*]] to i32
-; CHECK-NEXT: [[B:%.*]] = sext i8 [[Y:%.*]] to i32
-; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[A]], [[B]]
+; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = zext i8 %x to i32
@@ -145,9 +141,7 @@ define i1 @zext_sext_ugt(i8 %x, i8 %y) {
define i1 @zext_sext_eq(i8 %x, i8 %y) {
; CHECK-LABEL: @zext_sext_eq(
-; CHECK-NEXT: [[A:%.*]] = zext i8 [[X:%.*]] to i32
-; CHECK-NEXT: [[B:%.*]] = sext i8 [[Y:%.*]] to i32
-; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[A]], [[B]]
+; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = zext i8 %x to i32
@@ -158,9 +152,8 @@ define i1 @zext_sext_eq(i8 %x, i8 %y) {
define i1 @zext_sext_sle_op0_narrow(i8 %x, i16 %y) {
; CHECK-LABEL: @zext_sext_sle_op0_narrow(
-; CHECK-NEXT: [[A:%.*]] = zext i8 [[X:%.*]] to i32
-; CHECK-NEXT: [[B:%.*]] = sext i16 [[Y:%.*]] to i32
-; CHECK-NEXT: [[C:%.*]] = icmp sle i32 [[A]], [[B]]
+; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i16
+; CHECK-NEXT: [[C:%.*]] = icmp sle i16 [[TMP1]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = zext i8 %x to i32
@@ -171,9 +164,8 @@ define i1 @zext_sext_sle_op0_narrow(i8 %x, i16 %y) {
define i1 @zext_sext_ule_op0_wide(i9 %x, i8 %y) {
; CHECK-LABEL: @zext_sext_ule_op0_wide(
-; CHECK-NEXT: [[A:%.*]] = zext i9 [[X:%.*]] to i32
-; CHECK-NEXT: [[B:%.*]] = sext i8 [[Y:%.*]] to i32
-; CHECK-NEXT: [[C:%.*]] = icmp ule i32 [[A]], [[B]]
+; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[Y:%.*]] to i9
+; CHECK-NEXT: [[C:%.*]] = icmp uge i9 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = zext i9 %x to i32
@@ -184,9 +176,7 @@ define i1 @zext_sext_ule_op0_wide(i9 %x, i8 %y) {
define i1 @sext_zext_slt(i8 %x, i8 %y) {
; CHECK-LABEL: @sext_zext_slt(
-; CHECK-NEXT: [[A:%.*]] = sext i8 [[X:%.*]] to i32
-; CHECK-NEXT: [[B:%.*]] = zext i8 [[Y:%.*]] to i32
-; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[A]], [[B]]
+; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = sext i8 %x to i32
@@ -197,9 +187,7 @@ define i1 @sext_zext_slt(i8 %x, i8 %y) {
define i1 @sext_zext_ult(i8 %x, i8 %y) {
; CHECK-LABEL: @sext_zext_ult(
-; CHECK-NEXT: [[A:%.*]] = sext i8 [[X:%.*]] to i32
-; CHECK-NEXT: [[B:%.*]] = zext i8 [[Y:%.*]] to i32
-; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A]], [[B]]
+; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = sext i8 %x to i32
@@ -210,9 +198,7 @@ define i1 @sext_zext_ult(i8 %x, i8 %y) {
define <2 x i1> @sext_zext_ne(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @sext_zext_ne(
-; CHECK-NEXT: [[A:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i32>
-; CHECK-NEXT: [[B:%.*]] = zext <2 x i8> [[Y:%.*]] to <2 x i32>
-; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[A]], [[B]]
+; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%a = sext <2 x i8> %x to <2 x i32>
@@ -223,9 +209,8 @@ define <2 x i1> @sext_zext_ne(<2 x i8> %x, <2 x i8> %y) {
define i1 @sext_zext_sge_op0_narrow(i5 %x, i8 %y) {
; CHECK-LABEL: @sext_zext_sge_op0_narrow(
-; CHECK-NEXT: [[A:%.*]] = sext i5 [[X:%.*]] to i32
-; CHECK-NEXT: [[B:%.*]] = zext i8 [[Y:%.*]] to i32
-; CHECK-NEXT: [[C:%.*]] = icmp sge i32 [[A]], [[B]]
+; CHECK-NEXT: [[TMP1:%.*]] = sext i5 [[X:%.*]] to i8
+; CHECK-NEXT: [[C:%.*]] = icmp sge i8 [[TMP1]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = sext i5 %x to i32
@@ -236,9 +221,8 @@ define i1 @sext_zext_sge_op0_narrow(i5 %x, i8 %y) {
define i1 @sext_zext_uge_op0_wide(i16 %x, i8 %y) {
; CHECK-LABEL: @sext_zext_uge_op0_wide(
-; CHECK-NEXT: [[A:%.*]] = sext i16 [[X:%.*]] to i32
-; CHECK-NEXT: [[B:%.*]] = zext i8 [[Y:%.*]] to i32
-; CHECK-NEXT: [[C:%.*]] = icmp uge i32 [[A]], [[B]]
+; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[Y:%.*]] to i16
+; CHECK-NEXT: [[C:%.*]] = icmp ule i16 [[TMP1]], [[X:%.*]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = sext i16 %x to i32
@@ -396,9 +380,8 @@ define i1 @zext_eq_sext(i1 %a, i1 %b) {
define i1 @zext_eq_sext_fail_not_i1(i1 %a, i8 %b) {
; CHECK-LABEL: @zext_eq_sext_fail_not_i1(
-; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[A:%.*]] to i32
-; CHECK-NEXT: [[CONV3_NEG:%.*]] = sext i8 [[B:%.*]] to i32
-; CHECK-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[CONV]], [[CONV3_NEG]]
+; CHECK-NEXT: [[TMP1:%.*]] = sext i1 [[A:%.*]] to i8
+; CHECK-NEXT: [[TOBOOL4:%.*]] = icmp eq i8 [[TMP1]], [[B:%.*]]
; CHECK-NEXT: ret i1 [[TOBOOL4]]
;
%conv = zext i1 %a to i32
diff --git a/llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll b/llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll
index 90b2c123081fb49..4e9597f7e70daaa 100644
--- a/llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll
+++ b/llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --tool ./bin/opt --version 3
; See PRXXX for more details
-; RUN: opt < %s -S -passes=ipsccp | FileCheck %s
+; RUN-./bin/opt: opt < %s -S -passes=ipsccp | FileCheck %s
define signext i32 @sext_sext(i16 %x, i16 %y) {
>From f3d39f2005c1c124f07aaee7efd9192e1c7cfcc5 Mon Sep 17 00:00:00 2001
From: leo-ard <lool4516 at gmail.com>
Date: Tue, 31 Oct 2023 13:54:29 -0400
Subject: [PATCH 4/9] Move test to InstCombine
---
llvm/test/Transforms/{SCCP => InstCombine}/icmp-fold-with-cast.ll | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename llvm/test/Transforms/{SCCP => InstCombine}/icmp-fold-with-cast.ll (100%)
diff --git a/llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll b/llvm/test/Transforms/InstCombine/icmp-fold-with-cast.ll
similarity index 100%
rename from llvm/test/Transforms/SCCP/icmp-fold-with-cast.ll
rename to llvm/test/Transforms/InstCombine/icmp-fold-with-cast.ll
>From 02d1f8878983bf91689618bea4098d062e4bf9e0 Mon Sep 17 00:00:00 2001
From: leo-ard <lool4516 at gmail.com>
Date: Tue, 31 Oct 2023 13:58:55 -0400
Subject: [PATCH 5/9] Reformat according to git clang format
---
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 4751d870da7a777..30591ab0bea93a3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -5594,8 +5594,10 @@ Instruction *InstCombinerImpl::foldICmpWithZextOrSext(ICmpInst &ICmp) {
// If we have mismatched casts, treat the zext of a non-negative source as
// a sext to simulate matching casts. Otherwise, we are done.
// TODO: Can we handle some predicates (equality) without non-negative?
- if ((IsZext0 && (IsNonNeg0 || isKnownNonNegative(X, DL, 0, &AC, &ICmp, &DT))) ||
- (IsZext1 && (IsNonNeg1 || isKnownNonNegative(Y, DL, 0, &AC, &ICmp, &DT))))
+ if ((IsZext0 &&
+ (IsNonNeg0 || isKnownNonNegative(X, DL, 0, &AC, &ICmp, &DT))) ||
+ (IsZext1 &&
+ (IsNonNeg1 || isKnownNonNegative(Y, DL, 0, &AC, &ICmp, &DT))))
IsSignedExt = true;
else
return nullptr;
>From 2fc611be63c7c6b33d34d27ed7e649a409ba701e Mon Sep 17 00:00:00 2001
From: leo-ard <lool4516 at gmail.com>
Date: Wed, 1 Nov 2023 13:16:20 -0400
Subject: [PATCH 6/9] check with hasNonNeg (comment 2)
---
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 30591ab0bea93a3..96eec52b64ad35c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -5588,8 +5588,11 @@ Instruction *InstCombinerImpl::foldICmpWithZextOrSext(ICmpInst &ICmp) {
Constant::getNullValue(X->getType()));
// Treat "zext nneg" as "sext"
- bool IsNonNeg0 = isa<PossiblyNonNegInst>(ICmp.getOperand(0));
- bool IsNonNeg1 = isa<PossiblyNonNegInst>(ICmp.getOperand(1));
+ auto *NonNegInst0 = dyn_cast<PossiblyNonNegInst>(ICmp.getOperand(0));
+ auto *NonNegInst1 = dyn_cast<PossiblyNonNegInst>(ICmp.getOperand(1));
+
+ bool IsNonNeg0 = NonNegInst0 && NonNegInst0->hasNonNeg();
+ bool IsNonNeg1 = NonNegInst1 && NonNegInst1->hasNonNeg();
// If we have mismatched casts, treat the zext of a non-negative source as
// a sext to simulate matching casts. Otherwise, we are done.
>From d5fa339dcc881413a5b9d0a08fa5df78e2082a72 Mon Sep 17 00:00:00 2001
From: leo-ard <lool4516 at gmail.com>
Date: Wed, 1 Nov 2023 13:17:33 -0400
Subject: [PATCH 7/9] change test to instcombine (comment 3)
---
.../InstCombine/icmp-fold-with-cast.ll | 32 +++++++------------
1 file changed, 11 insertions(+), 21 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/icmp-fold-with-cast.ll b/llvm/test/Transforms/InstCombine/icmp-fold-with-cast.ll
index 4e9597f7e70daaa..119eb6faca7ca41 100644
--- a/llvm/test/Transforms/InstCombine/icmp-fold-with-cast.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-fold-with-cast.ll
@@ -1,14 +1,12 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --tool ./bin/opt --version 3
-; See PRXXX for more details
-; RUN-./bin/opt: opt < %s -S -passes=ipsccp | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; See PR-70845 for more details
+; RUN: opt < %s -S -passes=instcombine | FileCheck %s
define signext i32 @sext_sext(i16 %x, i16 %y) {
; CHECK-LABEL: define signext i32 @sext_sext(
; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[X]] to i32
-; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[Y]] to i32
; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i16 [[X]], [[Y]]
; CHECK-NEXT: br i1 [[CMP2]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.true:
@@ -41,9 +39,7 @@ define signext i32 @zext_zext(i16 %x, i16 %y) {
; CHECK-LABEL: define signext i32 @zext_zext(
; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[X]] to i32
-; CHECK-NEXT: [[CONV1:%.*]] = zext i16 [[Y]] to i32
-; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i16 [[X]], [[Y]]
+; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i16 [[X]], [[Y]]
; CHECK-NEXT: br i1 [[CMP2]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.true:
; CHECK-NEXT: br label [[COND_END:%.*]]
@@ -77,16 +73,14 @@ define signext i16 @zext_positive_and_sext(i32 noundef %n, ptr noundef %v) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_COND:%.*]]
; CHECK: for.cond:
-; CHECK-NEXT: [[P_0:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[CONV8:%.*]], [[COND_END:%.*]] ]
+; CHECK-NEXT: [[P_0:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[COND_OFF0:%.*]], [[COND_END:%.*]] ]
; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[COND_END]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
; CHECK: for.body:
-; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[P_0]] to i32
-; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[I_0]] to i64
+; CHECK-NEXT: [[IDXPROM:%.*]] = zext nneg i32 [[I_0]] to i64
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr i16, ptr [[V]], i64 [[IDXPROM]]
; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[ARRAYIDX]], align 2
-; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[TMP0]] to i32
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i16 [[P_0]], [[TMP0]]
; CHECK-NEXT: br i1 [[CMP2]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.true:
@@ -96,9 +90,8 @@ define signext i16 @zext_positive_and_sext(i32 noundef %n, ptr noundef %v) {
; CHECK: for.cond.cleanup:
; CHECK-NEXT: ret i16 [[P_0]]
; CHECK: cond.end:
-; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[CONV1]], [[COND_TRUE]] ], [ [[CONV]], [[COND_FALSE]] ]
-; CHECK-NEXT: [[CONV8]] = trunc i32 [[COND]] to i16
-; CHECK-NEXT: [[INC]] = add nsw i32 [[I_0]], 1
+; CHECK-NEXT: [[COND_OFF0]] = phi i16 [ [[TMP0]], [[COND_TRUE]] ], [ [[P_0]], [[COND_FALSE]] ]
+; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_0]], 1
; CHECK-NEXT: br label [[FOR_COND]]
;
entry:
@@ -143,20 +136,17 @@ define signext i16 @sext_and_zext_positive(i16 %x) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_COND:%.*]]
; CHECK: for.cond:
-; CHECK-NEXT: [[V:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[COND_END:%.*]] ]
+; CHECK-NEXT: [[V:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[A:%.*]], [[COND_END:%.*]] ]
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
-; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[V]] to i32
-; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[X]] to i32
-; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i16 [[X]], [[V]]
+; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i16 [[V]], [[X]]
; CHECK-NEXT: br i1 [[CMP2]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.true:
; CHECK-NEXT: br label [[COND_END]]
; CHECK: cond.false:
; CHECK-NEXT: br label [[COND_END]]
; CHECK: cond.end:
-; CHECK-NEXT: [[A:%.*]] = phi i16 [ 10, [[COND_TRUE]] ], [ 20, [[COND_FALSE]] ]
-; CHECK-NEXT: [[INC]] = add nuw nsw i16 [[A]], 1
+; CHECK-NEXT: [[A]] = phi i16 [ 11, [[COND_TRUE]] ], [ 21, [[COND_FALSE]] ]
; CHECK-NEXT: br label [[FOR_COND]]
;
entry:
>From 24bf4314042e678fa751ea388f53ccc7a8d5bb02 Mon Sep 17 00:00:00 2001
From: leo-ard <lool4516 at gmail.com>
Date: Wed, 1 Nov 2023 15:04:55 -0400
Subject: [PATCH 8/9] Moving end-to-end test to PhaseOrdering (comment 3)
---
clang/test/CodeGen/X86/min_max.c | 19 ---
.../Transforms/PhaseOrdering/min_max_loop.ll | 126 ++++++++++++++++++
2 files changed, 126 insertions(+), 19 deletions(-)
delete mode 100644 clang/test/CodeGen/X86/min_max.c
create mode 100644 llvm/test/Transforms/PhaseOrdering/min_max_loop.ll
diff --git a/clang/test/CodeGen/X86/min_max.c b/clang/test/CodeGen/X86/min_max.c
deleted file mode 100644
index 7af8181cc9ff367..000000000000000
--- a/clang/test/CodeGen/X86/min_max.c
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: %clang_cc1 %s -O2 -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
-
-short vecreduce_smax_v2i16(int n, short* v)
-{
- // CHECK: @llvm.smax
- short p = 0;
- for (int i = 0; i < n; ++i)
- p = p < v[i] ? v[i] : p;
- return p;
-}
-
-short vecreduce_smin_v2i16(int n, short* v)
-{
- // CHECK: @llvm.smin
- short p = 0;
- for (int i = 0; i < n; ++i)
- p = p > v[i] ? v[i] : p;
- return p;
-}
\ No newline at end of file
diff --git a/llvm/test/Transforms/PhaseOrdering/min_max_loop.ll b/llvm/test/Transforms/PhaseOrdering/min_max_loop.ll
new file mode 100644
index 000000000000000..7ea389dfafce68b
--- /dev/null
+++ b/llvm/test/Transforms/PhaseOrdering/min_max_loop.ll
@@ -0,0 +1,126 @@
+; RUN: opt < %s --O3 -S | FileCheck %s
+
+define signext i16 @vecreduce_smax_v2i16(i32 noundef %0, ptr noundef %1) #0 {
+ ;; CHECK: @llvm.smax
+ %3 = alloca i32, align 4
+ %4 = alloca ptr, align 8
+ %5 = alloca i16, align 2
+ %6 = alloca i32, align 4
+ store i32 %0, ptr %3, align 4
+ store ptr %1, ptr %4, align 8
+ store i16 0, ptr %5, align 2
+ store i32 0, ptr %6, align 4
+ br label %7
+
+ 7: ; preds = %34, %2
+ %8 = load i32, ptr %6, align 4
+ %9 = load i32, ptr %3, align 4
+ %10 = icmp slt i32 %8, %9
+ br i1 %10, label %11, label %37
+
+ 11: ; preds = %7
+ %12 = load i16, ptr %5, align 2
+ %13 = sext i16 %12 to i32
+ %14 = load ptr, ptr %4, align 8
+ %15 = load i32, ptr %6, align 4
+ %16 = sext i32 %15 to i64
+ %17 = getelementptr inbounds i16, ptr %14, i64 %16
+ %18 = load i16, ptr %17, align 2
+ %19 = sext i16 %18 to i32
+ %20 = icmp slt i32 %13, %19
+ br i1 %20, label %21, label %28
+
+ 21: ; preds = %11
+ %22 = load ptr, ptr %4, align 8
+ %23 = load i32, ptr %6, align 4
+ %24 = sext i32 %23 to i64
+ %25 = getelementptr inbounds i16, ptr %22, i64 %24
+ %26 = load i16, ptr %25, align 2
+ %27 = sext i16 %26 to i32
+ br label %31
+
+ 28: ; preds = %11
+ %29 = load i16, ptr %5, align 2
+ %30 = sext i16 %29 to i32
+ br label %31
+
+ 31: ; preds = %28, %21
+ %32 = phi i32 [ %27, %21 ], [ %30, %28 ]
+ %33 = trunc i32 %32 to i16
+ store i16 %33, ptr %5, align 2
+ br label %34
+
+ 34: ; preds = %31
+ %35 = load i32, ptr %6, align 4
+ %36 = add nsw i32 %35, 1
+ store i32 %36, ptr %6, align 4
+ br label %7
+
+ 37: ; preds = %7
+ %38 = load i16, ptr %5, align 2
+ ret i16 %38
+ }
+
+define signext i16 @vecreduce_smin_v2i16(i32 noundef %0, ptr noundef %1) #0 {
+; CHECK: @llvm.smin
+ %3 = alloca i32, align 4
+ %4 = alloca ptr, align 8
+ %5 = alloca i16, align 2
+ %6 = alloca i32, align 4
+ store i32 %0, ptr %3, align 4
+ store ptr %1, ptr %4, align 8
+ store i16 0, ptr %5, align 2
+ store i32 0, ptr %6, align 4
+ br label %7
+
+7: ; preds = %34, %2
+ %8 = load i32, ptr %6, align 4
+ %9 = load i32, ptr %3, align 4
+ %10 = icmp slt i32 %8, %9
+ br i1 %10, label %11, label %37
+
+11: ; preds = %7
+ %12 = load i16, ptr %5, align 2
+ %13 = sext i16 %12 to i32
+ %14 = load ptr, ptr %4, align 8
+ %15 = load i32, ptr %6, align 4
+ %16 = sext i32 %15 to i64
+ %17 = getelementptr inbounds i16, ptr %14, i64 %16
+ %18 = load i16, ptr %17, align 2
+ %19 = sext i16 %18 to i32
+ %20 = icmp sgt i32 %13, %19
+ br i1 %20, label %21, label %28
+
+21: ; preds = %11
+ %22 = load ptr, ptr %4, align 8
+ %23 = load i32, ptr %6, align 4
+ %24 = sext i32 %23 to i64
+ %25 = getelementptr inbounds i16, ptr %22, i64 %24
+ %26 = load i16, ptr %25, align 2
+ %27 = sext i16 %26 to i32
+ br label %31
+
+28: ; preds = %11
+ %29 = load i16, ptr %5, align 2
+ %30 = sext i16 %29 to i32
+ br label %31
+
+31: ; preds = %28, %21
+ %32 = phi i32 [ %27, %21 ], [ %30, %28 ]
+ %33 = trunc i32 %32 to i16
+ store i16 %33, ptr %5, align 2
+ br label %34
+
+34: ; preds = %31
+ %35 = load i32, ptr %6, align 4
+ %36 = add nsw i32 %35, 1
+ store i32 %36, ptr %6, align 4
+ br label %7
+
+37: ; preds = %7
+ %38 = load i16, ptr %5, align 2
+ ret i16 %38
+}
+
+
+
>From fb714bdb7e444a9e1da3f10283cd6470cdce964c Mon Sep 17 00:00:00 2001
From: leo-ard <lool4516 at gmail.com>
Date: Wed, 1 Nov 2023 16:02:28 -0400
Subject: [PATCH 9/9] Fixing failing reg tests
---
...004-11-27-SetCCForCastLargerAndConstant.ll | 5 +-
.../Transforms/InstCombine/icmp-ext-ext.ll | 49 +++++++++++++------
.../InstCombine/icmp-fold-with-cast.ll | 4 +-
3 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll b/llvm/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll
index b24a71b8dc15ea6..2e70a95dfde6233 100644
--- a/llvm/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll
+++ b/llvm/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll
@@ -403,8 +403,9 @@ define i1 @different_size_sext_sext_ule(i7 %x, i4 %y) {
define i1 @different_size_sext_zext_ne(i7 %x, i4 %y) {
; CHECK-LABEL: @different_size_sext_zext_ne(
-; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y:%.*]] to i7
-; CHECK-NEXT: [[R:%.*]] = icmp ne i7 [[TMP1]], [[X:%.*]]
+; CHECK-NEXT: [[SX:%.*]] = sext i7 [[X:%.*]] to i25
+; CHECK-NEXT: [[ZY:%.*]] = zext i4 [[Y:%.*]] to i25
+; CHECK-NEXT: [[R:%.*]] = icmp ne i25 [[SX]], [[ZY]]
; CHECK-NEXT: ret i1 [[R]]
;
%sx = sext i7 %x to i25
diff --git a/llvm/test/Transforms/InstCombine/icmp-ext-ext.ll b/llvm/test/Transforms/InstCombine/icmp-ext-ext.ll
index 87532c1faff1526..f70e48e27384619 100644
--- a/llvm/test/Transforms/InstCombine/icmp-ext-ext.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-ext-ext.ll
@@ -119,7 +119,9 @@ define <2 x i1> @sext_sext_uge_op0_wide(<2 x i16> %x, <2 x i8> %y) {
define i1 @zext_sext_sgt(i8 %x, i8 %y) {
; CHECK-LABEL: @zext_sext_sgt(
-; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[A:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT: [[B:%.*]] = sext i8 [[Y:%.*]] to i32
+; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], [[B]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = zext i8 %x to i32
@@ -130,7 +132,9 @@ define i1 @zext_sext_sgt(i8 %x, i8 %y) {
define i1 @zext_sext_ugt(i8 %x, i8 %y) {
; CHECK-LABEL: @zext_sext_ugt(
-; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[A:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT: [[B:%.*]] = sext i8 [[Y:%.*]] to i32
+; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[A]], [[B]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = zext i8 %x to i32
@@ -141,7 +145,9 @@ define i1 @zext_sext_ugt(i8 %x, i8 %y) {
define i1 @zext_sext_eq(i8 %x, i8 %y) {
; CHECK-LABEL: @zext_sext_eq(
-; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[A:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT: [[B:%.*]] = sext i8 [[Y:%.*]] to i32
+; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[A]], [[B]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = zext i8 %x to i32
@@ -152,8 +158,9 @@ define i1 @zext_sext_eq(i8 %x, i8 %y) {
define i1 @zext_sext_sle_op0_narrow(i8 %x, i16 %y) {
; CHECK-LABEL: @zext_sext_sle_op0_narrow(
-; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i16
-; CHECK-NEXT: [[C:%.*]] = icmp sle i16 [[TMP1]], [[Y:%.*]]
+; CHECK-NEXT: [[A:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT: [[B:%.*]] = sext i16 [[Y:%.*]] to i32
+; CHECK-NEXT: [[C:%.*]] = icmp sle i32 [[A]], [[B]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = zext i8 %x to i32
@@ -164,8 +171,9 @@ define i1 @zext_sext_sle_op0_narrow(i8 %x, i16 %y) {
define i1 @zext_sext_ule_op0_wide(i9 %x, i8 %y) {
; CHECK-LABEL: @zext_sext_ule_op0_wide(
-; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[Y:%.*]] to i9
-; CHECK-NEXT: [[C:%.*]] = icmp uge i9 [[TMP1]], [[X:%.*]]
+; CHECK-NEXT: [[A:%.*]] = zext i9 [[X:%.*]] to i32
+; CHECK-NEXT: [[B:%.*]] = sext i8 [[Y:%.*]] to i32
+; CHECK-NEXT: [[C:%.*]] = icmp ule i32 [[A]], [[B]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = zext i9 %x to i32
@@ -176,7 +184,9 @@ define i1 @zext_sext_ule_op0_wide(i9 %x, i8 %y) {
define i1 @sext_zext_slt(i8 %x, i8 %y) {
; CHECK-LABEL: @sext_zext_slt(
-; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[A:%.*]] = sext i8 [[X:%.*]] to i32
+; CHECK-NEXT: [[B:%.*]] = zext i8 [[Y:%.*]] to i32
+; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[A]], [[B]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = sext i8 %x to i32
@@ -187,7 +197,9 @@ define i1 @sext_zext_slt(i8 %x, i8 %y) {
define i1 @sext_zext_ult(i8 %x, i8 %y) {
; CHECK-LABEL: @sext_zext_ult(
-; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[A:%.*]] = sext i8 [[X:%.*]] to i32
+; CHECK-NEXT: [[B:%.*]] = zext i8 [[Y:%.*]] to i32
+; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A]], [[B]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = sext i8 %x to i32
@@ -198,7 +210,9 @@ define i1 @sext_zext_ult(i8 %x, i8 %y) {
define <2 x i1> @sext_zext_ne(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @sext_zext_ne(
-; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[A:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i32>
+; CHECK-NEXT: [[B:%.*]] = zext <2 x i8> [[Y:%.*]] to <2 x i32>
+; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[A]], [[B]]
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%a = sext <2 x i8> %x to <2 x i32>
@@ -209,8 +223,9 @@ define <2 x i1> @sext_zext_ne(<2 x i8> %x, <2 x i8> %y) {
define i1 @sext_zext_sge_op0_narrow(i5 %x, i8 %y) {
; CHECK-LABEL: @sext_zext_sge_op0_narrow(
-; CHECK-NEXT: [[TMP1:%.*]] = sext i5 [[X:%.*]] to i8
-; CHECK-NEXT: [[C:%.*]] = icmp sge i8 [[TMP1]], [[Y:%.*]]
+; CHECK-NEXT: [[A:%.*]] = sext i5 [[X:%.*]] to i32
+; CHECK-NEXT: [[B:%.*]] = zext i8 [[Y:%.*]] to i32
+; CHECK-NEXT: [[C:%.*]] = icmp sge i32 [[A]], [[B]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = sext i5 %x to i32
@@ -221,8 +236,9 @@ define i1 @sext_zext_sge_op0_narrow(i5 %x, i8 %y) {
define i1 @sext_zext_uge_op0_wide(i16 %x, i8 %y) {
; CHECK-LABEL: @sext_zext_uge_op0_wide(
-; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[Y:%.*]] to i16
-; CHECK-NEXT: [[C:%.*]] = icmp ule i16 [[TMP1]], [[X:%.*]]
+; CHECK-NEXT: [[A:%.*]] = sext i16 [[X:%.*]] to i32
+; CHECK-NEXT: [[B:%.*]] = zext i8 [[Y:%.*]] to i32
+; CHECK-NEXT: [[C:%.*]] = icmp uge i32 [[A]], [[B]]
; CHECK-NEXT: ret i1 [[C]]
;
%a = sext i16 %x to i32
@@ -380,8 +396,9 @@ define i1 @zext_eq_sext(i1 %a, i1 %b) {
define i1 @zext_eq_sext_fail_not_i1(i1 %a, i8 %b) {
; CHECK-LABEL: @zext_eq_sext_fail_not_i1(
-; CHECK-NEXT: [[TMP1:%.*]] = sext i1 [[A:%.*]] to i8
-; CHECK-NEXT: [[TOBOOL4:%.*]] = icmp eq i8 [[TMP1]], [[B:%.*]]
+; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[A:%.*]] to i32
+; CHECK-NEXT: [[CONV3_NEG:%.*]] = sext i8 [[B:%.*]] to i32
+; CHECK-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[CONV]], [[CONV3_NEG]]
; CHECK-NEXT: ret i1 [[TOBOOL4]]
;
%conv = zext i1 %a to i32
diff --git a/llvm/test/Transforms/InstCombine/icmp-fold-with-cast.ll b/llvm/test/Transforms/InstCombine/icmp-fold-with-cast.ll
index 119eb6faca7ca41..f9933c7f3aff228 100644
--- a/llvm/test/Transforms/InstCombine/icmp-fold-with-cast.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-fold-with-cast.ll
@@ -104,7 +104,7 @@ for.cond: ; preds = %cond.end, %entry
br i1 %cmp, label %for.body, label %for.cond.cleanup
for.body: ; preds = %for.cond
- %conv = zext i16 %p.0 to i32 ;; %p.0 is always positive here
+ %conv = zext nneg i16 %p.0 to i32 ;; %p.0 is always positive here
%idxprom = sext i32 %i.0 to i64
%arrayidx = getelementptr i16, ptr %v, i64 %idxprom
%0 = load i16, ptr %arrayidx, align 2
@@ -157,7 +157,7 @@ for.cond: ; preds = %cond.end, %entry
br label %for.body
for.body: ; preds = %for.cond
- %conv = zext i16 %v to i32 ;; %p.0 is always positive here
+ %conv = zext nneg i16 %v to i32 ;; %p.0 is always positive here
%conv1 = sext i16 %x to i32 ;; %p.0 is always positive here
%cmp2 = icmp slt i32 %conv1, %conv ;; positive/positive
br i1 %cmp2, label %cond.true, label %cond.false
More information about the cfe-commits
mailing list