[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
https://github.com/dtcxzyw requested changes to this pull request. https://github.com/llvm/llvm-project/pull/70845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
@@ -0,0 +1,175 @@ +; 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:[[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:[[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:%.*]] +; 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:%.*]] ], [ [[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:[[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:[[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_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: + 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 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 + %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.t
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
@@ -0,0 +1,175 @@ +; 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) { dtcxzyw wrote: Please drop unused `signext` and `noundef` flags. https://github.com/llvm/llvm-project/pull/70845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
@@ -5587,11 +5587,20 @@ Instruction *InstCombinerImpl::foldICmpWithZextOrSext(ICmpInst &ICmp) { return new ICmpInst(ICmp.getPredicate(), Builder.CreateOr(X, Y), Constant::getNullValue(X->getType())); + // Treat "zext nneg" as "sext" + auto *NonNegInst0 = dyn_cast(ICmp.getOperand(0)); + auto *NonNegInst1 = dyn_cast(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. // 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))) || nikic wrote: After rebasing over https://github.com/llvm/llvm-project/commit/5918f62301788b53e7d3a23f3203c483e9d4d791 it's possible to drop the isKnownNonNegative() call here entirely. We should only check for zext nneg. https://github.com/llvm/llvm-project/pull/70845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
@@ -0,0 +1,126 @@ +; RUN: opt < %s --O3 -S | FileCheck %s + +define signext i16 @vecreduce_smax_v2i16(i32 noundef %0, ptr noundef %1) #0 { nikic wrote: I think the point of these tests is to check interaction between IPSCCP and InstCombine, so a PhaseOrdering test makes sense. However, in the current form these tests are too hard to understand. I would suggest getting the IR again with `-fno-discard-value-names` and then running `opt -S -passes=sroa` over it to convert it into SSA form. https://github.com/llvm/llvm-project/pull/70845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
@@ -0,0 +1,175 @@ +; 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) { nikic wrote: Generally the tests in this file are not right for InstCombine. We should just directly check the min/max pattern with zext nneg there, nothing more. Preferably directly next to the existing tests for the transform (you can find them by commenting out the transform and seeing which tests break). https://github.com/llvm/llvm-project/pull/70845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
https://github.com/leo-ard updated https://github.com/llvm/llvm-project/pull/70845 From 00d0c18b5414ffe7222e1ee0ad5ecfdb8783704e Mon Sep 17 00:00:00 2001 From: leo-ard Date: Mon, 30 Oct 2023 18:01:27 -0400 Subject: [PATCH 01/13] 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 7c2ad92f919a3cc..cd287d757fdfd23 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -5554,11 +5554,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(ICmp.getOperand(0)); + bool IsNonNeg1 = isa(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 ee1978946530e28ff79f924bcc5ffd73dc590549 Mon Sep 17 00:00:00 2001 From: leo-ard Date: Mon, 30 Oct 2023 18:03:44 -0400 Subject: [PATCH 02/13] 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 000..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 000..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:
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
https://github.com/leo-ard edited https://github.com/llvm/llvm-project/pull/70845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
https://github.com/leo-ard updated https://github.com/llvm/llvm-project/pull/70845 From 00d0c18b5414ffe7222e1ee0ad5ecfdb8783704e Mon Sep 17 00:00:00 2001 From: leo-ard Date: Mon, 30 Oct 2023 18:01:27 -0400 Subject: [PATCH 01/14] 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 7c2ad92f919a3cc..cd287d757fdfd23 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -5554,11 +5554,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(ICmp.getOperand(0)); + bool IsNonNeg1 = isa(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 ee1978946530e28ff79f924bcc5ffd73dc590549 Mon Sep 17 00:00:00 2001 From: leo-ard Date: Mon, 30 Oct 2023 18:03:44 -0400 Subject: [PATCH 02/14] 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 000..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 000..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:
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
@@ -0,0 +1,112 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 +; RUN: opt < %s -O3 -S | FileCheck %s +; See issue #55013 and PR #70845 for more details. +; This test comes from the following C program, compiled with clang +; +;; short vecreduce_smin_v2i16(int n, short* v) +;; { +;; short p = 0; +;; for (int i = 0; i < n; ++i) +;; p = p > v[i] ? v[i] : p; +;; return p; +;; } +; +;; short vecreduce_smax_v2i16(int n, short* v) +;; { +;; short p = 0; +;; for (int i = 0; i < n; ++i) +;; p = p < v[i] ? v[i] : p; +;; return p; +;; } + +define i16 @vecreduce_smin_v2i16(i32 %n, ptr %v) { +; CHECK-LABEL: define i16 @vecreduce_smin_v2i16( +; CHECK:@llvm.smin.v2i16 leo-ard wrote: I didn't keep all the checks generated by `llvm/utils/update_test_checks.py` as in this tests, we only want to know if the intrinsics @llvm.smin.v2i16 has been generated or not. Let me know if you think I should leave all the checks https://github.com/llvm/llvm-project/pull/70845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
https://github.com/leo-ard edited https://github.com/llvm/llvm-project/pull/70845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
https://github.com/leo-ard updated https://github.com/llvm/llvm-project/pull/70845 From 00d0c18b5414ffe7222e1ee0ad5ecfdb8783704e Mon Sep 17 00:00:00 2001 From: leo-ard Date: Mon, 30 Oct 2023 18:01:27 -0400 Subject: [PATCH 01/15] 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 7c2ad92f919a3cc..cd287d757fdfd23 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -5554,11 +5554,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(ICmp.getOperand(0)); + bool IsNonNeg1 = isa(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 ee1978946530e28ff79f924bcc5ffd73dc590549 Mon Sep 17 00:00:00 2001 From: leo-ard Date: Mon, 30 Oct 2023 18:03:44 -0400 Subject: [PATCH 02/15] 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 000..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 000..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:
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
https://github.com/nikic approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/70845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [InstCombine] Use zext's nneg flag for icmp folding (PR #70845)
https://github.com/nikic edited https://github.com/llvm/llvm-project/pull/70845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [InstCombine] Use zext's nneg flag for icmp folding (PR #70845)
https://github.com/dtcxzyw approved this pull request. LGTM. Thank you! Do you have the access to merge PR? https://github.com/llvm/llvm-project/pull/70845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
https://github.com/leo-ard created https://github.com/llvm/llvm-project/pull/70845 This PR fixes https://github.com/llvm/llvm-project/issues/55013 : the max intrinsics is not generated for this simple loop case : https://godbolt.org/z/hxz1xhMPh. This is caused by a ICMP not being folded into a select, thus not generating the max intrinsics. For the story : Since LLVM 14, SCCP pass got smarter by folding sext into zext for positive ranges : https://reviews.llvm.org/D81756. After this change, InstCombine was sometimes unable to fold ICMP correctly as both of the arguments pointed to mismatched zext/sext. To fix this, @rotateright implemented this fix : https://reviews.llvm.org/D124419 that tries to resolve the mismatch by knowing if the argument of a zext is positive (in which case, it is like a sext) by using ValueTracking, however ValueTracking is not smart enough to infer that the value is positive in some cases. Recently, @nikic implemented #67982 which keeps the information that a zext is non-negative. This PR simply uses this information to do the folding accordingly. TLDR : This PR uses the recent nneg tag on zext to fold the icmp accordingly in instcombine. This PR also contains test cases for sext/zext folding with InstCombine as well as a x86 regression tests for the max/min case. From 7db32deed74766a9318eec5bceb3bdd069996e98 Mon Sep 17 00:00:00 2001 From: leo-ard Date: Mon, 30 Oct 2023 18:01:27 -0400 Subject: [PATCH 1/5] 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 2ff27abc79318c4..e9b448b2a7a2b97 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(ICmp.getOperand(0)); + bool IsNonNeg1 = isa(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 aacf6e9bff0b70ca063d9c9435a2877a133e0ea1 Mon Sep 17 00:00:00 2001 From: leo-ard Date: Mon, 30 Oct 2023 18:03:44 -0400 Subject: [PATCH 2/5] 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 000..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 000..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:%.*
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
llvmbot wrote: @llvm/pr-subscribers-backend-x86 Author: Léonard Oest O'Leary (leo-ard) Changes This PR fixes https://github.com/llvm/llvm-project/issues/55013 : the max intrinsics is not generated for this simple loop case : https://godbolt.org/z/hxz1xhMPh. This is caused by a ICMP not being folded into a select, thus not generating the max intrinsics. For the story : Since LLVM 14, SCCP pass got smarter by folding sext into zext for positive ranges : https://reviews.llvm.org/D81756. After this change, InstCombine was sometimes unable to fold ICMP correctly as both of the arguments pointed to mismatched zext/sext. To fix this, @rotateright implemented this fix : https://reviews.llvm.org/D124419 that tries to resolve the mismatch by knowing if the argument of a zext is positive (in which case, it is like a sext) by using ValueTracking, however ValueTracking is not smart enough to infer that the value is positive in some cases. Recently, @nikic implemented #67982 which keeps the information that a zext is non-negative. This PR simply uses this information to do the folding accordingly. TLDR : This PR uses the recent nneg tag on zext to fold the icmp accordingly in instcombine. This PR also contains test cases for sext/zext folding with InstCombine as well as a x86 regression tests for the max/min case. --- Full diff: https://github.com/llvm/llvm-project/pull/70845.diff 5 Files Affected: - (added) clang/test/CodeGen/X86/min_max.c (+19) - (modified) llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp (+8-2) - (modified) llvm/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll (+2-3) - (modified) llvm/test/Transforms/InstCombine/icmp-ext-ext.ll (+16-33) - (added) llvm/test/Transforms/InstCombine/icmp-fold-with-cast.ll (+185) ``diff diff --git a/clang/test/CodeGen/X86/min_max.c b/clang/test/CodeGen/X86/min_max.c new file mode 100644 index 000..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/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 2ff27abc79318c4..572872397b6baae 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -5587,11 +5587,17 @@ 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(ICmp.getOperand(0)); + bool IsNonNeg1 = isa(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; 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 +
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
@@ -0,0 +1,19 @@ +// RUN: %clang_cc1 %s -O2 -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s nikic wrote: We don't test end-to-end codegen with clang. If you want to test this, you should take the unoptimized clang IR and create a test in the llvm/test/PhaseOrdering directory using it. https://github.com/llvm/llvm-project/pull/70845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
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 Date: Mon, 30 Oct 2023 18:01:27 -0400 Subject: [PATCH 1/8] 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(ICmp.getOperand(0)); + bool IsNonNeg1 = isa(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 Date: Mon, 30 Oct 2023 18:03:44 -0400 Subject: [PATCH 2/8] 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 000..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 000..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:
[clang] [llvm] [Instcombine] use zext's nneg flag for icmp folding (PR #70845)
@@ -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-./bin/opt: opt < %s -S -passes=ipsccp | FileCheck %s leo-ard wrote: yep, a typo on my end https://github.com/llvm/llvm-project/pull/70845 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits