[llvm] [GVN] Replace cmp with not instruction if inv cmp is found (PR #223171)
Andreas Jonson via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 13 07:38:34 PDT 2026
https://github.com/andjo403 updated https://github.com/llvm/llvm-project/pull/223171
>From 04c79aa9803d5bb2e81543998525a83e21a8c004 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Sat, 12 Sep 2026 22:26:00 +0200
Subject: [PATCH 1/5] [GVN] pre commit test (NFC)
---
llvm/test/Transforms/GVN/inverse-cmp.ll | 52 +++++++++++++++++++++++++
1 file changed, 52 insertions(+)
create mode 100644 llvm/test/Transforms/GVN/inverse-cmp.ll
diff --git a/llvm/test/Transforms/GVN/inverse-cmp.ll b/llvm/test/Transforms/GVN/inverse-cmp.ll
new file mode 100644
index 0000000000000..192a37d9917d0
--- /dev/null
+++ b/llvm/test/Transforms/GVN/inverse-cmp.ll
@@ -0,0 +1,52 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes=gvn -S < %s | FileCheck %s
+
+declare void @use(i1)
+
+define void @inverse_icmp(i32 %x,i32 %y) {
+; CHECK-LABEL: define void @inverse_icmp(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[UGT1:%.*]] = icmp ugt i32 [[X]], [[Y]]
+; CHECK-NEXT: call void @use(i1 [[UGT1]])
+; CHECK-NEXT: [[UGT1_NOT:%.*]] = icmp ule i32 [[X]], [[Y]]
+; CHECK-NEXT: call void @use(i1 [[UGT1_NOT]])
+; CHECK-NEXT: ret void
+;
+ %ugt1 = icmp ugt i32 %x, %y
+ call void @use(i1 %ugt1)
+ %ule1 = icmp ule i32 %x, %y
+ call void @use(i1 %ule1)
+ ret void
+}
+
+define void @inverse_fcmp(double %x,double %y) {
+; CHECK-LABEL: define void @inverse_fcmp(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[OGT1:%.*]] = fcmp ogt double [[X]], [[Y]]
+; CHECK-NEXT: call void @use(i1 [[OGT1]])
+; CHECK-NEXT: [[OGT1_NOT:%.*]] = fcmp ule double [[X]], [[Y]]
+; CHECK-NEXT: call void @use(i1 [[OGT1_NOT]])
+; CHECK-NEXT: ret void
+;
+ %ogt1 = fcmp ogt double %x, %y
+ call void @use(i1 %ogt1)
+ %ule1 = fcmp ule double %x, %y
+ call void @use(i1 %ule1)
+ ret void
+}
+
+define void @inverse_icmp_swaped(i32 %x,i32 %y) {
+; CHECK-LABEL: define void @inverse_icmp_swaped(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[UGT1:%.*]] = icmp ugt i32 [[X]], [[Y]]
+; CHECK-NEXT: call void @use(i1 [[UGT1]])
+; CHECK-NEXT: [[UGT1_NOT:%.*]] = icmp uge i32 [[Y]], [[X]]
+; CHECK-NEXT: call void @use(i1 [[UGT1_NOT]])
+; CHECK-NEXT: ret void
+;
+ %ugt = icmp ugt i32 %x, %y
+ call void @use(i1 %ugt)
+ %ule = icmp uge i32 %y, %x
+ call void @use(i1 %ule)
+ ret void
+}
>From aa395283078e8ee23d97974d2f87142de4d72f9c Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Sat, 12 Sep 2026 22:28:41 +0200
Subject: [PATCH 2/5] [GVN] Replace cmp with not instruction if cmp inv is
found.
---
llvm/lib/Transforms/Scalar/GVN.cpp | 32 +++++++++++++++++--------
llvm/test/Transforms/GVN/inverse-cmp.ll | 6 ++---
2 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index c8989a4c8e0d4..acad4b311b2cf 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -3445,18 +3445,30 @@ bool GVNPass::processInstruction(Instruction *I) {
}
}
- // If the number we were assigned was a brand new VN, then we don't
- // need to do a lookup to see if the number already exists
- // somewhere in the domtree: it can't!
- if (Num >= NextNum) {
- LeaderTable.insert(Num, I, I->getParent());
- return false;
- }
-
// Perform fast-path value-number based elimination of values inherited from
- // dominators.
- Value *Repl = findLeader(I->getParent(), Num);
+ // dominators, unless if the number we were assigned was a brand new VN, then
+ // we don't need to do a lookup to see if the number already exists somewhere
+ // in the domtree: it can't!
+ Value *Repl = Num < NextNum ? findLeader(I->getParent(), Num) : nullptr;
if (!Repl) {
+ // substiut cmp instruction with not if possible.
+ if (CmpInst *Cmp = dyn_cast<CmpInst>(I)) {
+ uint32_t NextNumNot = VN.getNextUnusedValueNumber();
+ uint32_t NotNum =
+ VN.lookupOrAddCmp(Cmp->getOpcode(), Cmp->getInversePredicate(),
+ Cmp->getOperand(0), Cmp->getOperand(1));
+ if (NotNum < NextNumNot) {
+ Value *NotRepl = findLeader(I->getParent(), NotNum);
+ if (NotRepl && NotRepl != I) {
+ BinaryOperator *Not = BinaryOperator::CreateNot(
+ NotRepl, NotRepl->getName() + ".not", I->getIterator());
+ Not->setDebugLoc(I->getDebugLoc());
+ I->replaceAllUsesWith(Not);
+ salvageAndRemoveInstruction(I);
+ return true;
+ }
+ }
+ }
// Failure, just remember this instance for future use.
LeaderTable.insert(Num, I, I->getParent());
return false;
diff --git a/llvm/test/Transforms/GVN/inverse-cmp.ll b/llvm/test/Transforms/GVN/inverse-cmp.ll
index 192a37d9917d0..b874cd55b873a 100644
--- a/llvm/test/Transforms/GVN/inverse-cmp.ll
+++ b/llvm/test/Transforms/GVN/inverse-cmp.ll
@@ -8,7 +8,7 @@ define void @inverse_icmp(i32 %x,i32 %y) {
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
; CHECK-NEXT: [[UGT1:%.*]] = icmp ugt i32 [[X]], [[Y]]
; CHECK-NEXT: call void @use(i1 [[UGT1]])
-; CHECK-NEXT: [[UGT1_NOT:%.*]] = icmp ule i32 [[X]], [[Y]]
+; CHECK-NEXT: [[UGT1_NOT:%.*]] = xor i1 [[UGT1]], true
; CHECK-NEXT: call void @use(i1 [[UGT1_NOT]])
; CHECK-NEXT: ret void
;
@@ -24,7 +24,7 @@ define void @inverse_fcmp(double %x,double %y) {
; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
; CHECK-NEXT: [[OGT1:%.*]] = fcmp ogt double [[X]], [[Y]]
; CHECK-NEXT: call void @use(i1 [[OGT1]])
-; CHECK-NEXT: [[OGT1_NOT:%.*]] = fcmp ule double [[X]], [[Y]]
+; CHECK-NEXT: [[OGT1_NOT:%.*]] = xor i1 [[OGT1]], true
; CHECK-NEXT: call void @use(i1 [[OGT1_NOT]])
; CHECK-NEXT: ret void
;
@@ -40,7 +40,7 @@ define void @inverse_icmp_swaped(i32 %x,i32 %y) {
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
; CHECK-NEXT: [[UGT1:%.*]] = icmp ugt i32 [[X]], [[Y]]
; CHECK-NEXT: call void @use(i1 [[UGT1]])
-; CHECK-NEXT: [[UGT1_NOT:%.*]] = icmp uge i32 [[Y]], [[X]]
+; CHECK-NEXT: [[UGT1_NOT:%.*]] = xor i1 [[UGT1]], true
; CHECK-NEXT: call void @use(i1 [[UGT1_NOT]])
; CHECK-NEXT: ret void
;
>From 0e998ac700a8c66f1e5f247e0ffafb8c2debc2c7 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Sat, 12 Sep 2026 23:22:46 +0200
Subject: [PATCH 3/5] fixup! [GVN] Replace cmp with not instruction if cmp inv
is found.
---
llvm/test/Transforms/GVN/condprop.ll | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/llvm/test/Transforms/GVN/condprop.ll b/llvm/test/Transforms/GVN/condprop.ll
index eec1ea4a0abca..e963d8876f722 100644
--- a/llvm/test/Transforms/GVN/condprop.ll
+++ b/llvm/test/Transforms/GVN/condprop.ll
@@ -280,7 +280,7 @@ different:
define i1 @test6(i32 %x, i32 %y) {
; CHECK-LABEL: @test6(
; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]]
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[CMP2]], true
; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
; CHECK: same:
; CHECK-NEXT: ret i1 false
@@ -302,7 +302,7 @@ different:
define i1 @test6_fp(float %x, float %y) {
; CHECK-LABEL: @test6_fp(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp une float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[X]], [[Y]]
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[CMP2]], true
; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
; CHECK: same:
; CHECK-NEXT: ret i1 false
@@ -327,7 +327,7 @@ define i1 @test6_phi1(i1 %c, i32 %x, i32 %y) {
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
; CHECK: bb1:
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]]
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[CMP_NOT]], true
; CHECK-NEXT: br i1 [[CMP]], label [[BB2]], label [[BB3:%.*]]
; CHECK: bb2:
; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ false, [[BB1]] ], [ true, [[ENTRY:%.*]] ]
@@ -357,7 +357,7 @@ define i1 @test6_phi2(i1 %c, i32 %x, i32 %y) {
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]]
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[CMP_NOT]], true
; CHECK-NEXT: br i1 [[CMP]], label [[BB2]], label [[BB3:%.*]]
; CHECK: bb2:
; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ false, [[BB1]] ], [ true, [[ENTRY:%.*]] ]
@@ -426,7 +426,7 @@ different:
define i1 @test8(i32 %x, i32 %y) {
; CHECK-LABEL: @test8(
; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], [[Y]]
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[CMP2]], true
; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
; CHECK: same:
; CHECK-NEXT: ret i1 false
@@ -448,7 +448,7 @@ different:
define i1 @test8_fp(float %x, float %y) {
; CHECK-LABEL: @test8_fp(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X]], [[Y]]
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[CMP2]], true
; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
; CHECK: same:
; CHECK-NEXT: ret i1 false
>From 7e8265a6730a874bf26ac3cfa39d67dd27784fb1 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Sun, 13 Sep 2026 12:48:27 +0200
Subject: [PATCH 4/5] fixup! fixup! [GVN] Replace cmp with not instruction if
cmp inv is found.
---
llvm/include/llvm/Transforms/Scalar/GVN.h | 2 ++
llvm/lib/Transforms/Scalar/GVN.cpp | 13 +++++++++----
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Scalar/GVN.h b/llvm/include/llvm/Transforms/Scalar/GVN.h
index 82684dcafc0f4..f5dab9f51c231 100644
--- a/llvm/include/llvm/Transforms/Scalar/GVN.h
+++ b/llvm/include/llvm/Transforms/Scalar/GVN.h
@@ -216,6 +216,8 @@ class GVNPass : public OptionalPassInfoMixin<GVNPass> {
LLVM_ABI uint32_t lookup(Value *V, bool Verify = true) const;
LLVM_ABI uint32_t lookupOrAddCmp(unsigned Opcode, CmpInst::Predicate Pred,
Value *LHS, Value *RHS);
+ LLVM_ABI uint32_t lookupCmp(unsigned Opcode, CmpInst::Predicate Pred,
+ Value *LHS, Value *RHS);
LLVM_ABI uint32_t lookupPtrToInt(Value *Ptr, Type *Ty);
LLVM_ABI uint32_t phiTranslate(const BasicBlock *BB,
const BasicBlock *PhiBlock, uint32_t Num,
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index acad4b311b2cf..34d9e7e20c68e 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -765,6 +765,12 @@ uint32_t GVNPass::ValueTable::lookupOrAddCmp(unsigned Opcode,
Expression Exp = createCmpExpr(Opcode, Predicate, LHS, RHS);
return assignExpNewValueNum(Exp).first;
}
+uint32_t GVNPass::ValueTable::lookupCmp(unsigned Opcode,
+ CmpInst::Predicate Predicate,
+ Value *LHS, Value *RHS) {
+ Expression Exp = createCmpExpr(Opcode, Predicate, LHS, RHS);
+ return ExpressionNumbering.lookup(Exp);
+}
/// Returns the value number of ptrtoint \p Ptr to \Ty.
uint32_t GVNPass::ValueTable::lookupPtrToInt(Value *Ptr, Type *Ty) {
@@ -3453,11 +3459,10 @@ bool GVNPass::processInstruction(Instruction *I) {
if (!Repl) {
// substiut cmp instruction with not if possible.
if (CmpInst *Cmp = dyn_cast<CmpInst>(I)) {
- uint32_t NextNumNot = VN.getNextUnusedValueNumber();
uint32_t NotNum =
- VN.lookupOrAddCmp(Cmp->getOpcode(), Cmp->getInversePredicate(),
- Cmp->getOperand(0), Cmp->getOperand(1));
- if (NotNum < NextNumNot) {
+ VN.lookupCmp(Cmp->getOpcode(), Cmp->getInversePredicate(),
+ Cmp->getOperand(0), Cmp->getOperand(1));
+ if (NotNum != 0) {
Value *NotRepl = findLeader(I->getParent(), NotNum);
if (NotRepl && NotRepl != I) {
BinaryOperator *Not = BinaryOperator::CreateNot(
>From ec686db6d396ae21a6bcff0c13f926d03d12290b Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Sun, 13 Sep 2026 16:38:20 +0200
Subject: [PATCH 5/5] fixup! fixup! fixup! [GVN] Replace cmp with not
instruction if cmp inv is found.
---
llvm/lib/Transforms/Scalar/GVN.cpp | 11 ++-
llvm/test/Transforms/GVN/inverse-cmp.ll | 96 +++++++++++++++++++++++++
2 files changed, 105 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 34d9e7e20c68e..427f7b6e7a64d 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -3457,14 +3457,21 @@ bool GVNPass::processInstruction(Instruction *I) {
// in the domtree: it can't!
Value *Repl = Num < NextNum ? findLeader(I->getParent(), Num) : nullptr;
if (!Repl) {
- // substiut cmp instruction with not if possible.
+ // substitute cmp instruction with not if possible.
if (CmpInst *Cmp = dyn_cast<CmpInst>(I)) {
uint32_t NotNum =
VN.lookupCmp(Cmp->getOpcode(), Cmp->getInversePredicate(),
Cmp->getOperand(0), Cmp->getOperand(1));
if (NotNum != 0) {
Value *NotRepl = findLeader(I->getParent(), NotNum);
- if (NotRepl && NotRepl != I) {
+ auto FlagCheck = [&]() {
+ if (auto *Icmp = dyn_cast<ICmpInst>(NotRepl))
+ return !Icmp->hasSameSign() ||
+ Icmp->hasSameSign() == cast<ICmpInst>(I)->hasSameSign();
+ return cast<FPMathOperator>(NotRepl)->getFastMathFlags() ==
+ cast<FPMathOperator>(I)->getFastMathFlags();
+ };
+ if (NotRepl && NotRepl != I && FlagCheck()) {
BinaryOperator *Not = BinaryOperator::CreateNot(
NotRepl, NotRepl->getName() + ".not", I->getIterator());
Not->setDebugLoc(I->getDebugLoc());
diff --git a/llvm/test/Transforms/GVN/inverse-cmp.ll b/llvm/test/Transforms/GVN/inverse-cmp.ll
index b874cd55b873a..c1e98e2719389 100644
--- a/llvm/test/Transforms/GVN/inverse-cmp.ll
+++ b/llvm/test/Transforms/GVN/inverse-cmp.ll
@@ -19,6 +19,54 @@ define void @inverse_icmp(i32 %x,i32 %y) {
ret void
}
+define void @inverse_icmp_samesign_1(i32 %x,i32 %y) {
+; CHECK-LABEL: define void @inverse_icmp_samesign_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[UGT1:%.*]] = icmp ugt i32 [[X]], [[Y]]
+; CHECK-NEXT: call void @use(i1 [[UGT1]])
+; CHECK-NEXT: [[ULE1:%.*]] = xor i1 [[UGT1]], true
+; CHECK-NEXT: call void @use(i1 [[ULE1]])
+; CHECK-NEXT: ret void
+;
+ %ugt1 = icmp ugt i32 %x, %y
+ call void @use(i1 %ugt1)
+ %ule1 = icmp samesign ule i32 %x, %y
+ call void @use(i1 %ule1)
+ ret void
+}
+
+define void @inverse_icmp_samesign_2(i32 %x,i32 %y) {
+; CHECK-LABEL: define void @inverse_icmp_samesign_2(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[UGT1:%.*]] = icmp samesign ugt i32 [[X]], [[Y]]
+; CHECK-NEXT: call void @use(i1 [[UGT1]])
+; CHECK-NEXT: [[UGT1_NOT:%.*]] = xor i1 [[UGT1]], true
+; CHECK-NEXT: call void @use(i1 [[UGT1_NOT]])
+; CHECK-NEXT: ret void
+;
+ %ugt1 = icmp samesign ugt i32 %x, %y
+ call void @use(i1 %ugt1)
+ %ule1 = icmp samesign ule i32 %x, %y
+ call void @use(i1 %ule1)
+ ret void
+}
+
+define void @neg_inverse_icmp_samesign(i32 %x,i32 %y) {
+; CHECK-LABEL: define void @neg_inverse_icmp_samesign(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[UGT1:%.*]] = icmp samesign ugt i32 [[X]], [[Y]]
+; CHECK-NEXT: call void @use(i1 [[UGT1]])
+; CHECK-NEXT: [[ULE1:%.*]] = icmp ule i32 [[X]], [[Y]]
+; CHECK-NEXT: call void @use(i1 [[ULE1]])
+; CHECK-NEXT: ret void
+;
+ %ugt1 = icmp samesign ugt i32 %x, %y
+ call void @use(i1 %ugt1)
+ %ule1 = icmp ule i32 %x, %y
+ call void @use(i1 %ule1)
+ ret void
+}
+
define void @inverse_fcmp(double %x,double %y) {
; CHECK-LABEL: define void @inverse_fcmp(
; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
@@ -35,6 +83,54 @@ define void @inverse_fcmp(double %x,double %y) {
ret void
}
+define void @inverse_fcmp_nnan(double %x,double %y) {
+; CHECK-LABEL: define void @inverse_fcmp_nnan(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[OGT1:%.*]] = fcmp nnan ogt double [[X]], [[Y]]
+; CHECK-NEXT: call void @use(i1 [[OGT1]])
+; CHECK-NEXT: [[OGT1_NOT:%.*]] = xor i1 [[OGT1]], true
+; CHECK-NEXT: call void @use(i1 [[OGT1_NOT]])
+; CHECK-NEXT: ret void
+;
+ %ogt1 = fcmp nnan ogt double %x, %y
+ call void @use(i1 %ogt1)
+ %ule1 = fcmp nnan ule double %x, %y
+ call void @use(i1 %ule1)
+ ret void
+}
+
+define void @neg_inverse_fcmp_nnan_1(double %x,double %y) {
+; CHECK-LABEL: define void @neg_inverse_fcmp_nnan_1(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[OGT1:%.*]] = fcmp nnan ogt double [[X]], [[Y]]
+; CHECK-NEXT: call void @use(i1 [[OGT1]])
+; CHECK-NEXT: [[ULE1:%.*]] = fcmp ule double [[X]], [[Y]]
+; CHECK-NEXT: call void @use(i1 [[ULE1]])
+; CHECK-NEXT: ret void
+;
+ %ogt1 = fcmp nnan ogt double %x, %y
+ call void @use(i1 %ogt1)
+ %ule1 = fcmp ule double %x, %y
+ call void @use(i1 %ule1)
+ ret void
+}
+
+define void @neg_inverse_fcmp_nnan_2(double %x,double %y) {
+; CHECK-LABEL: define void @neg_inverse_fcmp_nnan_2(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[OGT1:%.*]] = fcmp ogt double [[X]], [[Y]]
+; CHECK-NEXT: call void @use(i1 [[OGT1]])
+; CHECK-NEXT: [[ULE1:%.*]] = fcmp nnan ule double [[X]], [[Y]]
+; CHECK-NEXT: call void @use(i1 [[ULE1]])
+; CHECK-NEXT: ret void
+;
+ %ogt1 = fcmp ogt double %x, %y
+ call void @use(i1 %ogt1)
+ %ule1 = fcmp nnan ule double %x, %y
+ call void @use(i1 %ule1)
+ ret void
+}
+
define void @inverse_icmp_swaped(i32 %x,i32 %y) {
; CHECK-LABEL: define void @inverse_icmp_swaped(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
More information about the llvm-commits
mailing list