[llvm] [NVPTX] Add commutativity to SETP instructions to enable MachineCSE of inverted predicates (PR #191888)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 13 14:16:09 PDT 2026
https://github.com/modiking created https://github.com/llvm/llvm-project/pull/191888
Inverted predicates can be used freely in PTX. If we can invert a predicate and CSE the generating instruction we can save calculating the inverse.
Teach the NVPTX `commuteInstructionImpl` that SETP instructions can be inverted to allow CSEing with previous SETP that match the inverted form. This also inverts the branch users of the predicate to maintain correctness.
Currently only allow the SETP inversion if all users are branches. Future work can extend this to `sel` and `not` instructions.
**Depends on #191887** (the first commit in this PR is from that stacked PR and should be reviewed there).
Split from #185755 per reviewer feedback.
>From d3114dce53a041eb65b3910ad84eb93daab0d9c9 Mon Sep 17 00:00:00 2001
From: root <mmo at nvidia.com>
Date: Mon, 13 Apr 2026 14:03:18 -0700
Subject: [PATCH 1/2] [NVPTX] Add reverseBranchCondition and CBranchOther
Add CBranchOther instruction for inverted predicate branches (@!p bra)
and implement reverseBranchCondition to support branch condition
inversion. Update analyzeBranch, insertBranch, and removeBranch to
handle both CBranch and CBranchOther.
This enables passes like branch folding to properly reverse branch
conditions, and is a prerequisite for SETP predicate inversion CSE.
Made-with: Cursor
---
llvm/lib/Target/NVPTX/NVPTXInstrInfo.cpp | 33 ++++++++++----
llvm/lib/Target/NVPTX/NVPTXInstrInfo.h | 2 +
llvm/lib/Target/NVPTX/NVPTXInstrInfo.td | 2 +
llvm/test/CodeGen/NVPTX/i128.ll | 36 +++++++---------
llvm/test/CodeGen/NVPTX/jump-table.ll | 55 +++++++++++-------------
5 files changed, 69 insertions(+), 59 deletions(-)
diff --git a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.cpp b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.cpp
index db2d96f5ff532..3516106a918d8 100644
--- a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.cpp
@@ -99,10 +99,12 @@ bool NVPTXInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
if (LastInst.getOpcode() == NVPTX::GOTO) {
TBB = LastInst.getOperand(0).getMBB();
return false;
- } else if (LastInst.getOpcode() == NVPTX::CBranch) {
+ } else if (LastInst.getOpcode() == NVPTX::CBranch ||
+ LastInst.getOpcode() == NVPTX::CBranchOther) {
// Block ends with fall-through condbranch.
TBB = LastInst.getOperand(1).getMBB();
Cond.push_back(LastInst.getOperand(0));
+ Cond.push_back(MachineOperand::CreateImm(LastInst.getOpcode()));
return false;
}
// Otherwise, don't know what this is.
@@ -116,11 +118,13 @@ bool NVPTXInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
if (I != MBB.begin() && isUnpredicatedTerminator(*--I))
return true;
- // If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it.
- if (SecondLastInst.getOpcode() == NVPTX::CBranch &&
+ // If the block ends with a conditional branch and NVPTX::GOTO, handle it.
+ if ((SecondLastInst.getOpcode() == NVPTX::CBranch ||
+ SecondLastInst.getOpcode() == NVPTX::CBranchOther) &&
LastInst.getOpcode() == NVPTX::GOTO) {
TBB = SecondLastInst.getOperand(1).getMBB();
Cond.push_back(SecondLastInst.getOperand(0));
+ Cond.push_back(MachineOperand::CreateImm(SecondLastInst.getOpcode()));
FBB = LastInst.getOperand(0).getMBB();
return false;
}
@@ -147,7 +151,8 @@ unsigned NVPTXInstrInfo::removeBranch(MachineBasicBlock &MBB,
if (I == MBB.begin())
return 0;
--I;
- if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch)
+ if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch &&
+ I->getOpcode() != NVPTX::CBranchOther)
return 0;
// Remove the branch.
@@ -158,7 +163,7 @@ unsigned NVPTXInstrInfo::removeBranch(MachineBasicBlock &MBB,
if (I == MBB.begin())
return 1;
--I;
- if (I->getOpcode() != NVPTX::CBranch)
+ if (I->getOpcode() != NVPTX::CBranch && I->getOpcode() != NVPTX::CBranchOther)
return 1;
// Remove the branch.
@@ -176,7 +181,7 @@ unsigned NVPTXInstrInfo::insertBranch(MachineBasicBlock &MBB,
// Shouldn't be a fall through.
assert(TBB && "insertBranch must not be told to insert a fallthrough");
- assert((Cond.size() == 1 || Cond.size() == 0) &&
+ assert((Cond.size() == 2 || Cond.size() == 0) &&
"NVPTX branch conditions have two components!");
// One-way branch.
@@ -184,12 +189,24 @@ unsigned NVPTXInstrInfo::insertBranch(MachineBasicBlock &MBB,
if (Cond.empty()) // Unconditional branch
BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(TBB);
else // Conditional branch
- BuildMI(&MBB, DL, get(NVPTX::CBranch)).add(Cond[0]).addMBB(TBB);
+ BuildMI(&MBB, DL, get(Cond[1].getImm())).add(Cond[0]).addMBB(TBB);
return 1;
}
// Two-way Conditional Branch.
- BuildMI(&MBB, DL, get(NVPTX::CBranch)).add(Cond[0]).addMBB(TBB);
+ BuildMI(&MBB, DL, get(Cond[1].getImm())).add(Cond[0]).addMBB(TBB);
BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(FBB);
return 2;
}
+
+bool NVPTXInstrInfo::reverseBranchCondition(
+ SmallVectorImpl<MachineOperand> &Cond) const {
+ assert(Cond.size() == 2 && "Invalid NVPTX branch condition!");
+ if (Cond[1].getImm() == NVPTX::CBranch)
+ Cond[1].setImm(NVPTX::CBranchOther);
+ else if (Cond[1].getImm() == NVPTX::CBranchOther)
+ Cond[1].setImm(NVPTX::CBranch);
+ else
+ return true;
+ return false;
+}
diff --git a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.h b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.h
index 3c150b1e26785..c0b7e77cf63a5 100644
--- a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.h
+++ b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.h
@@ -67,6 +67,8 @@ class NVPTXInstrInfo : public NVPTXGenInstrInfo {
MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
const DebugLoc &DL,
int *BytesAdded = nullptr) const override;
+ bool
+ reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
};
} // namespace llvm
diff --git a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td
index 858635bc99815..d8ed1d20101a1 100644
--- a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td
+++ b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td
@@ -2422,6 +2422,8 @@ let isTerminator=1 in {
def CBranch : NVPTXInst<(outs), (ins B1:$a, brtarget:$target),
"@$a bra \t$target;",
[(brcond i1:$a, bb:$target)]>;
+ def CBranchOther : NVPTXInst<(outs), (ins B1:$a, brtarget:$target),
+ "@!$a bra \t$target;", []>;
let isBarrier=1 in
def GOTO : BasicNVPTXInst<(outs), (ins brtarget:$target),
diff --git a/llvm/test/CodeGen/NVPTX/i128.ll b/llvm/test/CodeGen/NVPTX/i128.ll
index 8a5e0a00a20eb..df1214c3f5e00 100644
--- a/llvm/test/CodeGen/NVPTX/i128.ll
+++ b/llvm/test/CodeGen/NVPTX/i128.ll
@@ -58,7 +58,7 @@ define i128 @srem_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: selp.b64 %rd77, 0, %rd2, %p13;
; CHECK-NEXT: or.pred %p15, %p13, %p14;
; CHECK-NEXT: @%p15 bra $L__BB0_5;
-; CHECK-NEXT: // %bb.3: // %udiv-bb1
+; CHECK-NEXT: // %bb.1: // %udiv-bb1
; CHECK-NEXT: add.cc.s64 %rd71, %rd27, 1;
; CHECK-NEXT: addc.cc.s64 %rd72, %rd28, 0;
; CHECK-NEXT: or.b64 %rd31, %rd71, %rd72;
@@ -77,7 +77,7 @@ define i128 @srem_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: mov.b64 %rd70, 0;
; CHECK-NEXT: mov.b64 %rd69, %rd70;
; CHECK-NEXT: @%p16 bra $L__BB0_4;
-; CHECK-NEXT: // %bb.1: // %udiv-preheader
+; CHECK-NEXT: // %bb.2: // %udiv-preheader
; CHECK-NEXT: cvt.u32.u64 %r9, %rd71;
; CHECK-NEXT: shr.u64 %rd36, %rd2, %r9;
; CHECK-NEXT: sub.s32 %r10, 64, %r9;
@@ -91,7 +91,7 @@ define i128 @srem_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: add.cc.s64 %rd6, %rd4, -1;
; CHECK-NEXT: addc.cc.s64 %rd7, %rd5, -1;
; CHECK-NEXT: mov.b64 %rd69, %rd70;
-; CHECK-NEXT: $L__BB0_2: // %udiv-do-while
+; CHECK-NEXT: $L__BB0_3: // %udiv-do-while
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
; CHECK-NEXT: shr.u64 %rd40, %rd73, 63;
; CHECK-NEXT: shl.b64 %rd41, %rd74, 1;
@@ -117,8 +117,7 @@ define i128 @srem_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: addc.cc.s64 %rd72, %rd72, -1;
; CHECK-NEXT: or.b64 %rd55, %rd71, %rd72;
; CHECK-NEXT: setp.eq.b64 %p19, %rd55, 0;
-; CHECK-NEXT: @%p19 bra $L__BB0_4;
-; CHECK-NEXT: bra.uni $L__BB0_2;
+; CHECK-NEXT: @!%p19 bra $L__BB0_3;
; CHECK-NEXT: $L__BB0_4: // %udiv-loop-exit
; CHECK-NEXT: shr.u64 %rd56, %rd75, 63;
; CHECK-NEXT: shl.b64 %rd57, %rd76, 1;
@@ -187,7 +186,7 @@ define i128 @urem_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: selp.b64 %rd64, 0, %rd5, %p11;
; CHECK-NEXT: or.pred %p13, %p11, %p12;
; CHECK-NEXT: @%p13 bra $L__BB1_5;
-; CHECK-NEXT: // %bb.3: // %udiv-bb1
+; CHECK-NEXT: // %bb.1: // %udiv-bb1
; CHECK-NEXT: add.cc.s64 %rd58, %rd18, 1;
; CHECK-NEXT: addc.cc.s64 %rd59, %rd19, 0;
; CHECK-NEXT: or.b64 %rd22, %rd58, %rd59;
@@ -206,7 +205,7 @@ define i128 @urem_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: mov.b64 %rd57, 0;
; CHECK-NEXT: mov.b64 %rd56, %rd57;
; CHECK-NEXT: @%p14 bra $L__BB1_4;
-; CHECK-NEXT: // %bb.1: // %udiv-preheader
+; CHECK-NEXT: // %bb.2: // %udiv-preheader
; CHECK-NEXT: cvt.u32.u64 %r9, %rd58;
; CHECK-NEXT: shr.u64 %rd27, %rd5, %r9;
; CHECK-NEXT: sub.s32 %r10, 64, %r9;
@@ -220,7 +219,7 @@ define i128 @urem_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: add.cc.s64 %rd3, %rd1, -1;
; CHECK-NEXT: addc.cc.s64 %rd4, %rd2, -1;
; CHECK-NEXT: mov.b64 %rd56, %rd57;
-; CHECK-NEXT: $L__BB1_2: // %udiv-do-while
+; CHECK-NEXT: $L__BB1_3: // %udiv-do-while
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
; CHECK-NEXT: shr.u64 %rd31, %rd60, 63;
; CHECK-NEXT: shl.b64 %rd32, %rd61, 1;
@@ -246,8 +245,7 @@ define i128 @urem_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: addc.cc.s64 %rd59, %rd59, -1;
; CHECK-NEXT: or.b64 %rd46, %rd58, %rd59;
; CHECK-NEXT: setp.eq.b64 %p17, %rd46, 0;
-; CHECK-NEXT: @%p17 bra $L__BB1_4;
-; CHECK-NEXT: bra.uni $L__BB1_2;
+; CHECK-NEXT: @!%p17 bra $L__BB1_3;
; CHECK-NEXT: $L__BB1_4: // %udiv-loop-exit
; CHECK-NEXT: shr.u64 %rd47, %rd62, 63;
; CHECK-NEXT: shl.b64 %rd48, %rd63, 1;
@@ -358,7 +356,7 @@ define i128 @sdiv_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: selp.b64 %rd72, 0, %rd1, %p13;
; CHECK-NEXT: or.pred %p15, %p13, %p14;
; CHECK-NEXT: @%p15 bra $L__BB4_5;
-; CHECK-NEXT: // %bb.3: // %udiv-bb1
+; CHECK-NEXT: // %bb.1: // %udiv-bb1
; CHECK-NEXT: add.cc.s64 %rd66, %rd28, 1;
; CHECK-NEXT: addc.cc.s64 %rd67, %rd29, 0;
; CHECK-NEXT: or.b64 %rd32, %rd66, %rd67;
@@ -377,7 +375,7 @@ define i128 @sdiv_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: mov.b64 %rd65, 0;
; CHECK-NEXT: mov.b64 %rd64, %rd65;
; CHECK-NEXT: @%p16 bra $L__BB4_4;
-; CHECK-NEXT: // %bb.1: // %udiv-preheader
+; CHECK-NEXT: // %bb.2: // %udiv-preheader
; CHECK-NEXT: cvt.u32.u64 %r9, %rd66;
; CHECK-NEXT: shr.u64 %rd37, %rd1, %r9;
; CHECK-NEXT: sub.s32 %r10, 64, %r9;
@@ -391,7 +389,7 @@ define i128 @sdiv_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: add.cc.s64 %rd6, %rd3, -1;
; CHECK-NEXT: addc.cc.s64 %rd7, %rd4, -1;
; CHECK-NEXT: mov.b64 %rd64, %rd65;
-; CHECK-NEXT: $L__BB4_2: // %udiv-do-while
+; CHECK-NEXT: $L__BB4_3: // %udiv-do-while
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
; CHECK-NEXT: shr.u64 %rd41, %rd68, 63;
; CHECK-NEXT: shl.b64 %rd42, %rd69, 1;
@@ -417,8 +415,7 @@ define i128 @sdiv_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: addc.cc.s64 %rd67, %rd67, -1;
; CHECK-NEXT: or.b64 %rd56, %rd66, %rd67;
; CHECK-NEXT: setp.eq.b64 %p19, %rd56, 0;
-; CHECK-NEXT: @%p19 bra $L__BB4_4;
-; CHECK-NEXT: bra.uni $L__BB4_2;
+; CHECK-NEXT: @!%p19 bra $L__BB4_3;
; CHECK-NEXT: $L__BB4_4: // %udiv-loop-exit
; CHECK-NEXT: shr.u64 %rd57, %rd70, 63;
; CHECK-NEXT: shl.b64 %rd58, %rd71, 1;
@@ -481,7 +478,7 @@ define i128 @udiv_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: selp.b64 %rd58, 0, %rd3, %p11;
; CHECK-NEXT: or.pred %p13, %p11, %p12;
; CHECK-NEXT: @%p13 bra $L__BB5_5;
-; CHECK-NEXT: // %bb.3: // %udiv-bb1
+; CHECK-NEXT: // %bb.1: // %udiv-bb1
; CHECK-NEXT: add.cc.s64 %rd52, %rd18, 1;
; CHECK-NEXT: addc.cc.s64 %rd53, %rd19, 0;
; CHECK-NEXT: or.b64 %rd22, %rd52, %rd53;
@@ -500,7 +497,7 @@ define i128 @udiv_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: mov.b64 %rd51, 0;
; CHECK-NEXT: mov.b64 %rd50, %rd51;
; CHECK-NEXT: @%p14 bra $L__BB5_4;
-; CHECK-NEXT: // %bb.1: // %udiv-preheader
+; CHECK-NEXT: // %bb.2: // %udiv-preheader
; CHECK-NEXT: cvt.u32.u64 %r9, %rd52;
; CHECK-NEXT: shr.u64 %rd27, %rd3, %r9;
; CHECK-NEXT: sub.s32 %r10, 64, %r9;
@@ -514,7 +511,7 @@ define i128 @udiv_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: add.cc.s64 %rd1, %rd5, -1;
; CHECK-NEXT: addc.cc.s64 %rd2, %rd6, -1;
; CHECK-NEXT: mov.b64 %rd50, %rd51;
-; CHECK-NEXT: $L__BB5_2: // %udiv-do-while
+; CHECK-NEXT: $L__BB5_3: // %udiv-do-while
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
; CHECK-NEXT: shr.u64 %rd31, %rd54, 63;
; CHECK-NEXT: shl.b64 %rd32, %rd55, 1;
@@ -540,8 +537,7 @@ define i128 @udiv_i128(i128 %lhs, i128 %rhs) {
; CHECK-NEXT: addc.cc.s64 %rd53, %rd53, -1;
; CHECK-NEXT: or.b64 %rd46, %rd52, %rd53;
; CHECK-NEXT: setp.eq.b64 %p17, %rd46, 0;
-; CHECK-NEXT: @%p17 bra $L__BB5_4;
-; CHECK-NEXT: bra.uni $L__BB5_2;
+; CHECK-NEXT: @!%p17 bra $L__BB5_3;
; CHECK-NEXT: $L__BB5_4: // %udiv-loop-exit
; CHECK-NEXT: shr.u64 %rd47, %rd56, 63;
; CHECK-NEXT: shl.b64 %rd48, %rd57, 1;
diff --git a/llvm/test/CodeGen/NVPTX/jump-table.ll b/llvm/test/CodeGen/NVPTX/jump-table.ll
index 4d391f85e978a..8f253f5861aea 100644
--- a/llvm/test/CodeGen/NVPTX/jump-table.ll
+++ b/llvm/test/CodeGen/NVPTX/jump-table.ll
@@ -53,9 +53,8 @@ define void @foo(i32 %i) {
; PTX50-NEXT: @%p4 bra $L__BB0_7;
; PTX50-NEXT: // %bb.2: // %entry
; PTX50-NEXT: setp.eq.b32 %p5, %r1, 1;
-; PTX50-NEXT: @%p5 bra $L__BB0_3;
-; PTX50-NEXT: bra.uni $L__BB0_9;
-; PTX50-NEXT: $L__BB0_3: // %case1
+; PTX50-NEXT: @!%p5 bra $L__BB0_9;
+; PTX50-NEXT: // %bb.3: // %case1
; PTX50-NEXT: st.global.b32 [out], 1;
; PTX50-NEXT: bra.uni $L__BB0_9;
; PTX50-NEXT: $L__BB0_4: // %entry
@@ -63,9 +62,8 @@ define void @foo(i32 %i) {
; PTX50-NEXT: @%p2 bra $L__BB0_8;
; PTX50-NEXT: // %bb.5: // %entry
; PTX50-NEXT: setp.eq.b32 %p3, %r1, 3;
-; PTX50-NEXT: @%p3 bra $L__BB0_6;
-; PTX50-NEXT: bra.uni $L__BB0_9;
-; PTX50-NEXT: $L__BB0_6: // %case3
+; PTX50-NEXT: @!%p3 bra $L__BB0_9;
+; PTX50-NEXT: // %bb.6: // %case3
; PTX50-NEXT: st.global.b32 [out], 3;
; PTX50-NEXT: bra.uni $L__BB0_9;
; PTX50-NEXT: $L__BB0_7: // %case0
@@ -116,18 +114,18 @@ define i32 @test2(i32 %tmp158) {
; PTX60-NEXT: @%p1 bra $L__BB1_4;
; PTX60-NEXT: // %bb.1: // %entry
; PTX60-NEXT: setp.lt.u32 %p4, %r1, 6;
-; PTX60-NEXT: @%p4 bra $L__BB1_3;
+; PTX60-NEXT: @%p4 bra $L__BB1_6;
; PTX60-NEXT: // %bb.2: // %entry
; PTX60-NEXT: setp.lt.s32 %p5, %r1, -2147483645;
-; PTX60-NEXT: @%p5 bra $L__BB1_3;
-; PTX60-NEXT: bra.uni $L__BB1_6;
+; PTX60-NEXT: @%p5 bra $L__BB1_6;
+; PTX60-NEXT: bra.uni $L__BB1_3;
; PTX60-NEXT: $L__BB1_4: // %entry
; PTX60-NEXT: add.s32 %r2, %r1, -120;
; PTX60-NEXT: setp.gt.u32 %p2, %r2, 5;
; PTX60-NEXT: @%p2 bra $L__BB1_5;
; PTX60-NEXT: // %bb.12: // %entry
; PTX60-NEXT: $L_brx_0: .branchtargets
-; PTX60-NEXT: $L__BB1_3,
+; PTX60-NEXT: $L__BB1_6,
; PTX60-NEXT: $L__BB1_7,
; PTX60-NEXT: $L__BB1_8,
; PTX60-NEXT: $L__BB1_9,
@@ -139,15 +137,14 @@ define i32 @test2(i32 %tmp158) {
; PTX60-NEXT: ret;
; PTX60-NEXT: $L__BB1_5: // %entry
; PTX60-NEXT: setp.eq.b32 %p3, %r1, 1024;
-; PTX60-NEXT: @%p3 bra $L__BB1_3;
-; PTX60-NEXT: bra.uni $L__BB1_6;
-; PTX60-NEXT: $L__BB1_3: // %bb338
+; PTX60-NEXT: @!%p3 bra $L__BB1_3;
+; PTX60-NEXT: $L__BB1_6: // %bb338
; PTX60-NEXT: st.param.b32 [func_retval0], 11;
; PTX60-NEXT: ret;
; PTX60-NEXT: $L__BB1_10: // %bb342
; PTX60-NEXT: st.param.b32 [func_retval0], 15;
; PTX60-NEXT: ret;
-; PTX60-NEXT: $L__BB1_6: // %bb336
+; PTX60-NEXT: $L__BB1_3: // %bb336
; PTX60-NEXT: st.param.b32 [func_retval0], 10;
; PTX60-NEXT: ret;
; PTX60-NEXT: $L__BB1_8: // %bb340
@@ -171,16 +168,15 @@ define i32 @test2(i32 %tmp158) {
; PTX50-NEXT: @%p1 bra $L__BB1_4;
; PTX50-NEXT: // %bb.1: // %entry
; PTX50-NEXT: setp.lt.u32 %p11, %r1, 6;
-; PTX50-NEXT: @%p11 bra $L__BB1_3;
+; PTX50-NEXT: @%p11 bra $L__BB1_15;
; PTX50-NEXT: // %bb.2: // %entry
; PTX50-NEXT: setp.lt.s32 %p12, %r1, -2147483645;
-; PTX50-NEXT: @%p12 bra $L__BB1_3;
-; PTX50-NEXT: bra.uni $L__BB1_15;
+; PTX50-NEXT: @%p12 bra $L__BB1_15;
+; PTX50-NEXT: bra.uni $L__BB1_3;
; PTX50-NEXT: $L__BB1_4: // %entry
; PTX50-NEXT: setp.gt.s32 %p2, %r1, 122;
-; PTX50-NEXT: @%p2 bra $L__BB1_9;
-; PTX50-NEXT: bra.uni $L__BB1_5;
-; PTX50-NEXT: $L__BB1_9: // %entry
+; PTX50-NEXT: @!%p2 bra $L__BB1_5;
+; PTX50-NEXT: // %bb.9: // %entry
; PTX50-NEXT: setp.gt.s32 %p3, %r1, 124;
; PTX50-NEXT: @%p3 bra $L__BB1_13;
; PTX50-NEXT: // %bb.10: // %entry
@@ -188,22 +184,20 @@ define i32 @test2(i32 %tmp158) {
; PTX50-NEXT: @%p6 bra $L__BB1_17;
; PTX50-NEXT: // %bb.11: // %entry
; PTX50-NEXT: setp.eq.b32 %p7, %r1, 124;
-; PTX50-NEXT: @%p7 bra $L__BB1_12;
-; PTX50-NEXT: bra.uni $L__BB1_15;
-; PTX50-NEXT: $L__BB1_12: // %bb342
+; PTX50-NEXT: @!%p7 bra $L__BB1_3;
+; PTX50-NEXT: // %bb.12: // %bb342
; PTX50-NEXT: st.param.b32 [func_retval0], 15;
; PTX50-NEXT: ret;
; PTX50-NEXT: $L__BB1_5: // %entry
; PTX50-NEXT: setp.eq.b32 %p8, %r1, 120;
-; PTX50-NEXT: @%p8 bra $L__BB1_3;
+; PTX50-NEXT: @%p8 bra $L__BB1_15;
; PTX50-NEXT: // %bb.6: // %entry
; PTX50-NEXT: setp.eq.b32 %p9, %r1, 121;
; PTX50-NEXT: @%p9 bra $L__BB1_16;
; PTX50-NEXT: // %bb.7: // %entry
; PTX50-NEXT: setp.eq.b32 %p10, %r1, 122;
-; PTX50-NEXT: @%p10 bra $L__BB1_8;
-; PTX50-NEXT: bra.uni $L__BB1_15;
-; PTX50-NEXT: $L__BB1_8: // %bb340
+; PTX50-NEXT: @!%p10 bra $L__BB1_3;
+; PTX50-NEXT: // %bb.8: // %bb340
; PTX50-NEXT: st.param.b32 [func_retval0], 13;
; PTX50-NEXT: ret;
; PTX50-NEXT: $L__BB1_13: // %entry
@@ -211,9 +205,8 @@ define i32 @test2(i32 %tmp158) {
; PTX50-NEXT: @%p4 bra $L__BB1_18;
; PTX50-NEXT: // %bb.14: // %entry
; PTX50-NEXT: setp.eq.b32 %p5, %r1, 1024;
-; PTX50-NEXT: @%p5 bra $L__BB1_3;
-; PTX50-NEXT: bra.uni $L__BB1_15;
-; PTX50-NEXT: $L__BB1_3: // %bb338
+; PTX50-NEXT: @!%p5 bra $L__BB1_3;
+; PTX50-NEXT: $L__BB1_15: // %bb338
; PTX50-NEXT: st.param.b32 [func_retval0], 11;
; PTX50-NEXT: ret;
; PTX50-NEXT: $L__BB1_17: // %bb341
@@ -222,7 +215,7 @@ define i32 @test2(i32 %tmp158) {
; PTX50-NEXT: $L__BB1_18: // %bb343
; PTX50-NEXT: st.param.b32 [func_retval0], 18;
; PTX50-NEXT: ret;
-; PTX50-NEXT: $L__BB1_15: // %bb336
+; PTX50-NEXT: $L__BB1_3: // %bb336
; PTX50-NEXT: st.param.b32 [func_retval0], 10;
; PTX50-NEXT: ret;
; PTX50-NEXT: $L__BB1_16: // %bb339
>From b79b68fefb1537d273e5e9779cc0fbb5ce4baf6e Mon Sep 17 00:00:00 2001
From: root <mmo at nvidia.com>
Date: Mon, 13 Apr 2026 14:05:18 -0700
Subject: [PATCH 2/2] [NVPTX] Add commutativity to SETP instructions to enable
MachineCSE of inverted predicates
Inverted predicates can be used freely in PTX. If we can invert a
predicate and CSE the generating instruction we can save calculating
the inverse.
Teach the NVPTX commuteInstructionImpl that SETP instructions can be
inverted to allow CSEing with previous SETP that match the inverted
form. This also inverts the branch users of the predicate to maintain
correctness.
Currently only allow the SETP inversion if all users are branches.
Future work can extend this to sel and not instructions.
Made-with: Cursor
---
llvm/lib/Target/NVPTX/NVPTXInstrInfo.cpp | 180 +++++
llvm/lib/Target/NVPTX/NVPTXInstrInfo.h | 8 +
llvm/lib/Target/NVPTX/NVPTXInstrInfo.td | 4 +-
...achine-cse-predicate-inversion-bfloat16.ll | 695 ++++++++++++++++++
...machine-cse-predicate-inversion-float16.ll | 695 ++++++++++++++++++
...machine-cse-predicate-inversion-float32.ll | 663 +++++++++++++++++
...machine-cse-predicate-inversion-float64.ll | 679 +++++++++++++++++
.../machine-cse-predicate-inversion-int16.ll | 437 +++++++++++
.../machine-cse-predicate-inversion-int32.ll | 427 +++++++++++
.../machine-cse-predicate-inversion-int64.ll | 437 +++++++++++
...-cse-predicate-inversion-multiple-users.ll | 50 ++
...ne-cse-predicate-inversion-vector-float.ll | 99 +++
...ine-cse-predicate-no-inversion-bfloat16.ll | 224 ++++++
...hine-cse-predicate-no-inversion-float16.ll | 224 ++++++
...hine-cse-predicate-no-inversion-float32.ll | 214 ++++++
...hine-cse-predicate-no-inversion-float64.ll | 219 ++++++
...achine-cse-predicate-no-inversion-int16.ll | 224 ++++++
...achine-cse-predicate-no-inversion-int32.ll | 219 ++++++
...achine-cse-predicate-no-inversion-int64.ll | 224 ++++++
19 files changed, 5920 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-bfloat16.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-float16.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-float32.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-float64.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-int16.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-int32.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-int64.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-multiple-users.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-vector-float.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-bfloat16.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-float16.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-float32.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-float64.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-int16.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-int32.ll
create mode 100644 llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-int64.ll
diff --git a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.cpp b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.cpp
index 3516106a918d8..4a9e0f44afc9c 100644
--- a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.cpp
@@ -16,6 +16,7 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include <optional>
using namespace llvm;
@@ -210,3 +211,182 @@ bool NVPTXInstrInfo::reverseBranchCondition(
return true;
return false;
}
+
+bool NVPTXInstrInfo::invertPredicateBranchInstr(MachineBasicBlock &MBB) const {
+ MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
+ SmallVector<MachineOperand, 4> Cond;
+ if (analyzeBranch(MBB, TBB, FBB, Cond, /*AllowModify=*/false))
+ return false;
+ if (Cond.empty())
+ return false;
+ if (reverseBranchCondition(Cond))
+ return false;
+ DebugLoc DL = MBB.findBranchDebugLoc();
+ removeBranch(MBB);
+ insertBranch(MBB, TBB, FBB, Cond, DL);
+ return true;
+}
+
+static bool isIntegerSetp(const MachineInstr &MI) {
+ switch (MI.getOpcode()) {
+ case NVPTX::SETP_i16rr:
+ case NVPTX::SETP_i16ri:
+ case NVPTX::SETP_i16ir:
+ case NVPTX::SETP_i32rr:
+ case NVPTX::SETP_i32ri:
+ case NVPTX::SETP_i32ir:
+ case NVPTX::SETP_i64rr:
+ case NVPTX::SETP_i64ri:
+ case NVPTX::SETP_i64ir:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool isFloatSetp(const MachineInstr &MI) {
+ switch (MI.getOpcode()) {
+ // TODO: Because these generate 2 predicates ISel doesn't duplicate the
+ // computation but rather directly lowers it to `not.pred` if we need the
+ // inverse. This means for patterns like these tests we would want to
+ // speculatively invert the `not.pred` instruction rather than the comparison.
+ // case NVPTX::SETP_bf16x2rr:
+ // case NVPTX::SETP_f16x2rr:
+ case NVPTX::SETP_bf16rr:
+ case NVPTX::SETP_f16rr:
+ case NVPTX::SETP_f32rr:
+ case NVPTX::SETP_f32ri:
+ case NVPTX::SETP_f32ir:
+ case NVPTX::SETP_f64rr:
+ case NVPTX::SETP_f64ri:
+ case NVPTX::SETP_f64ir:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static std::optional<int64_t> invertIntegerCmpMode(int64_t Mode) {
+ switch (Mode) {
+ case NVPTX::PTXCmpMode::EQ:
+ return NVPTX::PTXCmpMode::NE;
+ case NVPTX::PTXCmpMode::NE:
+ return NVPTX::PTXCmpMode::EQ;
+ case NVPTX::PTXCmpMode::LT:
+ return NVPTX::PTXCmpMode::GE;
+ case NVPTX::PTXCmpMode::LE:
+ return NVPTX::PTXCmpMode::GT;
+ case NVPTX::PTXCmpMode::GT:
+ return NVPTX::PTXCmpMode::LE;
+ case NVPTX::PTXCmpMode::GE:
+ return NVPTX::PTXCmpMode::LT;
+ case NVPTX::PTXCmpMode::LTU:
+ return NVPTX::PTXCmpMode::GEU;
+ case NVPTX::PTXCmpMode::LEU:
+ return NVPTX::PTXCmpMode::GTU;
+ case NVPTX::PTXCmpMode::GTU:
+ return NVPTX::PTXCmpMode::LEU;
+ case NVPTX::PTXCmpMode::GEU:
+ return NVPTX::PTXCmpMode::LTU;
+ default:
+ return std::nullopt;
+ }
+}
+
+static std::optional<int64_t> invertFloatCmpMode(int64_t Mode) {
+ switch (Mode) {
+ case NVPTX::PTXCmpMode::EQ:
+ return NVPTX::PTXCmpMode::NEU;
+ case NVPTX::PTXCmpMode::NE:
+ return NVPTX::PTXCmpMode::EQU;
+ case NVPTX::PTXCmpMode::EQU:
+ return NVPTX::PTXCmpMode::NE;
+ case NVPTX::PTXCmpMode::NEU:
+ return NVPTX::PTXCmpMode::EQ;
+ case NVPTX::PTXCmpMode::LT:
+ return NVPTX::PTXCmpMode::GEU;
+ case NVPTX::PTXCmpMode::LE:
+ return NVPTX::PTXCmpMode::GTU;
+ case NVPTX::PTXCmpMode::GT:
+ return NVPTX::PTXCmpMode::LEU;
+ case NVPTX::PTXCmpMode::GE:
+ return NVPTX::PTXCmpMode::LTU;
+ case NVPTX::PTXCmpMode::LTU:
+ return NVPTX::PTXCmpMode::GE;
+ case NVPTX::PTXCmpMode::LEU:
+ return NVPTX::PTXCmpMode::GT;
+ case NVPTX::PTXCmpMode::GTU:
+ return NVPTX::PTXCmpMode::LE;
+ case NVPTX::PTXCmpMode::GEU:
+ return NVPTX::PTXCmpMode::LT;
+ case NVPTX::PTXCmpMode::NUM:
+ return NVPTX::PTXCmpMode::NotANumber;
+ case NVPTX::PTXCmpMode::NotANumber:
+ return NVPTX::PTXCmpMode::NUM;
+ default:
+ return std::nullopt;
+ }
+}
+
+static bool invertCompareInstr(MachineInstr &MI) {
+ MachineOperand &ModeOp = MI.getOperand(3);
+ assert(ModeOp.isImm() && "SETP mode operand must be an immediate");
+
+ std::optional<int64_t> Inverted;
+ if (isIntegerSetp(MI))
+ Inverted = invertIntegerCmpMode(ModeOp.getImm());
+ else if (isFloatSetp(MI))
+ Inverted = invertFloatCmpMode(ModeOp.getImm());
+
+ if (!Inverted)
+ return false;
+
+ ModeOp.setImm(*Inverted);
+ return true;
+}
+
+bool NVPTXInstrInfo::findCommutedOpIndices(const MachineInstr &MI,
+ unsigned &SrcOpIdx1,
+ unsigned &SrcOpIdx2) const {
+ if (isIntegerSetp(MI) || isFloatSetp(MI))
+ return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
+ return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2);
+}
+
+MachineInstr *NVPTXInstrInfo::commuteInstructionImpl(MachineInstr &MI,
+ bool NewMI,
+ unsigned OpIdx1,
+ unsigned OpIdx2) const {
+ assert(!NewMI && "this should never be used");
+
+ if (!isIntegerSetp(MI) && !isFloatSetp(MI))
+ return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
+
+ if (!invertCompareInstr(MI))
+ return nullptr;
+
+ // For now all users must be invertible conditional branches.
+ // TODO: support other users such as selects.
+ bool AllInverted = true;
+ MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
+ for (MachineInstr &UseMI :
+ MRI.use_nodbg_instructions(MI.getOperand(0).getReg())) {
+ if (!(UseMI.isConditionalBranch() &&
+ invertPredicateBranchInstr(*UseMI.getParent()))) {
+ AllInverted = false;
+ break;
+ }
+ }
+
+ if (!AllInverted) {
+ for (MachineInstr &UseMI :
+ MRI.use_nodbg_instructions(MI.getOperand(0).getReg())) {
+ if (!(UseMI.isConditionalBranch() &&
+ invertPredicateBranchInstr(*UseMI.getParent())))
+ break;
+ }
+ invertCompareInstr(MI);
+ return nullptr;
+ }
+ return &MI;
+}
diff --git a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.h b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.h
index c0b7e77cf63a5..957fcf5cae69a 100644
--- a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.h
+++ b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.h
@@ -69,6 +69,14 @@ class NVPTXInstrInfo : public NVPTXGenInstrInfo {
int *BytesAdded = nullptr) const override;
bool
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
+ bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1,
+ unsigned &SrcOpIdx2) const override;
+ MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
+ unsigned OpIdx1,
+ unsigned OpIdx2) const override;
+
+private:
+ bool invertPredicateBranchInstr(MachineBasicBlock &MBB) const;
};
} // namespace llvm
diff --git a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td
index d8ed1d20101a1..13672097b072f 100644
--- a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td
+++ b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td
@@ -1568,7 +1568,7 @@ multiclass FSETP<RegTyInfo t, bit allow_ftz = true> {
defvar ftz_str = !if(allow_ftz, "$ftz", "");
defvar op_str = "setp.${cmp:FCmp}" # ftz_str # "." # t.PtxType;
defvar flags = !con((ins CmpMode:$cmp), !if(allow_ftz, (ins FTZFlag:$ftz), (ins)));
- let hasSideEffects = false in {
+ let hasSideEffects = false, isCompare = 1, isCommutable = 1 in {
def rr :
BasicFlagsNVPTXInst<(outs B1:$dst), (ins t.RC:$a, t.RC:$b),
flags, op_str>;
@@ -1594,7 +1594,7 @@ multiclass FSETP<RegTyInfo t, bit allow_ftz = true> {
multiclass ISETP<RegTyInfo t> {
defvar op_str = "setp.${cmp:ICmp}.${cmp:IType}" # t.Size;
- let hasSideEffects = false in {
+ let hasSideEffects = false, isCompare = 1, isCommutable = 1 in {
def rr :
BasicFlagsNVPTXInst<(outs B1:$dst), (ins t.RC:$a, t.RC:$b),
(ins CmpMode:$cmp), op_str>;
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-bfloat16.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-bfloat16.ll
new file mode 100644
index 0000000000000..b6b77e9c09108
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-bfloat16.ll
@@ -0,0 +1,695 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+; RUN: %if ptxas-sm_100 %{ llc < %s -march=nvptx64 -mcpu=sm_100 -O2 | %ptxas-verify -arch=sm_100 %}
+
+target triple = "nvptx64-nvidia-cuda"
+
+define i32 @test_bfloat16_eq(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_eq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_eq_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_eq_param_0];
+; CHECK-NEXT: setp.eq.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp une bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_ne(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_ne(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_ne_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_ne_param_0];
+; CHECK-NEXT: setp.ne.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp one bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ueq bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_oeq(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_oeq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_oeq_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_oeq_param_0];
+; CHECK-NEXT: setp.eq.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB2_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB2_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB2_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB2_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp une bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_one(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_one(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_one_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_one_param_0];
+; CHECK-NEXT: setp.ne.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB3_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB3_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB3_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB3_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp one bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ueq bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_ueq(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_ueq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_ueq_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_ueq_param_0];
+; CHECK-NEXT: setp.equ.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB4_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB4_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB4_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB4_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ueq bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp one bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_une(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_une(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_une_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_une_param_0];
+; CHECK-NEXT: setp.neu.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB5_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB5_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB5_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB5_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp une bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp oeq bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_olt(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_olt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_olt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_olt_param_0];
+; CHECK-NEXT: setp.lt.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB6_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB6_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB6_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB6_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp olt bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp uge bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_ole(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_ole(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_ole_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_ole_param_0];
+; CHECK-NEXT: setp.le.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB7_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB7_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB7_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB7_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ole bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ugt bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_ogt(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_ogt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_ogt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_ogt_param_0];
+; CHECK-NEXT: setp.gt.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB8_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB8_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB8_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB8_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ogt bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ule bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_oge(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_oge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_oge_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_oge_param_0];
+; CHECK-NEXT: setp.ge.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB9_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB9_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB9_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB9_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oge bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ult bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_ult(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_ult(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_ult_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_ult_param_0];
+; CHECK-NEXT: setp.ltu.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB10_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB10_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB10_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB10_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ult bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp oge bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_ule(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_ule(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_ule_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_ule_param_0];
+; CHECK-NEXT: setp.leu.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB11_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB11_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB11_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB11_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ule bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ogt bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_ugt(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_ugt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_ugt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_ugt_param_0];
+; CHECK-NEXT: setp.gtu.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB12_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB12_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB12_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB12_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ugt bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ole bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_uge(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_uge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_uge_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_uge_param_0];
+; CHECK-NEXT: setp.geu.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB13_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB13_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB13_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB13_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp uge bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp olt bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_ord(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_ord(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_ord_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_ord_param_0];
+; CHECK-NEXT: setp.num.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @!%p1 bra $L__BB14_1;
+; CHECK-NEXT: $L__BB14_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB14_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB14_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+; CHECK-NEXT: $L__BB14_1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: bra.uni $L__BB14_2;
+entry:
+ %cmp = fcmp ord bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp uno bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_uno(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_uno(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_uno_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_uno_param_0];
+; CHECK-NEXT: setp.nan.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB15_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB15_2: // %merge1
+; CHECK-NEXT: @%p1 bra $L__BB15_3;
+; CHECK-NEXT: $L__BB15_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+; CHECK-NEXT: $L__BB15_3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: bra.uni $L__BB15_4;
+entry:
+ %cmp = fcmp uno bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ord bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-float16.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-float16.ll
new file mode 100644
index 0000000000000..42aa05da4c76a
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-float16.ll
@@ -0,0 +1,695 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+; RUN: %if ptxas-sm_100 %{ llc < %s -march=nvptx64 -mcpu=sm_100 -O2 | %ptxas-verify -arch=sm_100 %}
+
+target triple = "nvptx64-nvidia-cuda"
+
+define i32 @test_float16_eq(half %a, half %b) {
+; CHECK-LABEL: test_float16_eq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_eq_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_eq_param_0];
+; CHECK-NEXT: setp.eq.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp une half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_ne(half %a, half %b) {
+; CHECK-LABEL: test_float16_ne(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_ne_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_ne_param_0];
+; CHECK-NEXT: setp.ne.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp one half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ueq half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_oeq(half %a, half %b) {
+; CHECK-LABEL: test_float16_oeq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_oeq_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_oeq_param_0];
+; CHECK-NEXT: setp.eq.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB2_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB2_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB2_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB2_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp une half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_one(half %a, half %b) {
+; CHECK-LABEL: test_float16_one(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_one_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_one_param_0];
+; CHECK-NEXT: setp.ne.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB3_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB3_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB3_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB3_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp one half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ueq half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_ueq(half %a, half %b) {
+; CHECK-LABEL: test_float16_ueq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_ueq_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_ueq_param_0];
+; CHECK-NEXT: setp.equ.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB4_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB4_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB4_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB4_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ueq half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp one half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_une(half %a, half %b) {
+; CHECK-LABEL: test_float16_une(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_une_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_une_param_0];
+; CHECK-NEXT: setp.neu.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB5_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB5_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB5_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB5_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp une half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp oeq half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_olt(half %a, half %b) {
+; CHECK-LABEL: test_float16_olt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_olt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_olt_param_0];
+; CHECK-NEXT: setp.lt.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB6_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB6_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB6_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB6_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp olt half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp uge half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_ole(half %a, half %b) {
+; CHECK-LABEL: test_float16_ole(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_ole_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_ole_param_0];
+; CHECK-NEXT: setp.le.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB7_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB7_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB7_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB7_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ole half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ugt half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_ogt(half %a, half %b) {
+; CHECK-LABEL: test_float16_ogt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_ogt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_ogt_param_0];
+; CHECK-NEXT: setp.gt.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB8_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB8_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB8_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB8_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ogt half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ule half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_oge(half %a, half %b) {
+; CHECK-LABEL: test_float16_oge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_oge_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_oge_param_0];
+; CHECK-NEXT: setp.ge.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB9_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB9_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB9_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB9_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oge half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ult half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_ult(half %a, half %b) {
+; CHECK-LABEL: test_float16_ult(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_ult_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_ult_param_0];
+; CHECK-NEXT: setp.ltu.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB10_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB10_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB10_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB10_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ult half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp oge half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_ule(half %a, half %b) {
+; CHECK-LABEL: test_float16_ule(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_ule_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_ule_param_0];
+; CHECK-NEXT: setp.leu.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB11_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB11_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB11_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB11_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ule half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ogt half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_ugt(half %a, half %b) {
+; CHECK-LABEL: test_float16_ugt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_ugt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_ugt_param_0];
+; CHECK-NEXT: setp.gtu.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB12_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB12_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB12_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB12_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ugt half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ole half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_uge(half %a, half %b) {
+; CHECK-LABEL: test_float16_uge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_uge_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_uge_param_0];
+; CHECK-NEXT: setp.geu.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB13_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB13_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB13_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB13_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp uge half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp olt half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_ord(half %a, half %b) {
+; CHECK-LABEL: test_float16_ord(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_ord_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_ord_param_0];
+; CHECK-NEXT: setp.num.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @!%p1 bra $L__BB14_1;
+; CHECK-NEXT: $L__BB14_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB14_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB14_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+; CHECK-NEXT: $L__BB14_1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: bra.uni $L__BB14_2;
+entry:
+ %cmp = fcmp ord half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp uno half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_uno(half %a, half %b) {
+; CHECK-LABEL: test_float16_uno(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_uno_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_uno_param_0];
+; CHECK-NEXT: setp.nan.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB15_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB15_2: // %merge1
+; CHECK-NEXT: @%p1 bra $L__BB15_3;
+; CHECK-NEXT: $L__BB15_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+; CHECK-NEXT: $L__BB15_3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: bra.uni $L__BB15_4;
+entry:
+ %cmp = fcmp uno half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ord half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-float32.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-float32.ll
new file mode 100644
index 0000000000000..a034ef25aea11
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-float32.ll
@@ -0,0 +1,663 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+; RUN: %if ptxas-sm_100 %{ llc < %s -march=nvptx64 -mcpu=sm_100 -O2 | %ptxas-verify -arch=sm_100 %}
+
+target triple = "nvptx64-nvidia-cuda"
+
+define i32 @test_float32_eq(float %arg) {
+; CHECK-LABEL: test_float32_eq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_eq_param_0];
+; CHECK-NEXT: setp.eq.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp une float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_ne(float %arg) {
+; CHECK-LABEL: test_float32_ne(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_ne_param_0];
+; CHECK-NEXT: setp.ne.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp one float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ueq float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_oeq(float %arg) {
+; CHECK-LABEL: test_float32_oeq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_oeq_param_0];
+; CHECK-NEXT: setp.eq.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB2_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB2_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB2_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB2_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp une float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_one(float %arg) {
+; CHECK-LABEL: test_float32_one(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_one_param_0];
+; CHECK-NEXT: setp.ne.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB3_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB3_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB3_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB3_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp one float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ueq float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_ueq(float %arg) {
+; CHECK-LABEL: test_float32_ueq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_ueq_param_0];
+; CHECK-NEXT: setp.equ.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB4_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB4_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB4_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB4_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ueq float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp one float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_une(float %arg) {
+; CHECK-LABEL: test_float32_une(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_une_param_0];
+; CHECK-NEXT: setp.neu.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB5_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB5_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB5_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB5_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp une float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp oeq float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_olt(float %arg) {
+; CHECK-LABEL: test_float32_olt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_olt_param_0];
+; CHECK-NEXT: setp.lt.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB6_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB6_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB6_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB6_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp olt float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp uge float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_ole(float %arg) {
+; CHECK-LABEL: test_float32_ole(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_ole_param_0];
+; CHECK-NEXT: setp.le.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB7_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB7_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB7_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB7_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ole float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ugt float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_ogt(float %arg) {
+; CHECK-LABEL: test_float32_ogt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_ogt_param_0];
+; CHECK-NEXT: setp.gt.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB8_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB8_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB8_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB8_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ogt float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ule float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_oge(float %arg) {
+; CHECK-LABEL: test_float32_oge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_oge_param_0];
+; CHECK-NEXT: setp.ge.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB9_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB9_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB9_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB9_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oge float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ult float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_ult(float %arg) {
+; CHECK-LABEL: test_float32_ult(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_ult_param_0];
+; CHECK-NEXT: setp.ltu.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB10_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB10_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB10_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB10_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ult float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp oge float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_ule(float %arg) {
+; CHECK-LABEL: test_float32_ule(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_ule_param_0];
+; CHECK-NEXT: setp.leu.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB11_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB11_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB11_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB11_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ule float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ogt float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_ugt(float %arg) {
+; CHECK-LABEL: test_float32_ugt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_ugt_param_0];
+; CHECK-NEXT: setp.gtu.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB12_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB12_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB12_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB12_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ugt float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ole float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_uge(float %arg) {
+; CHECK-LABEL: test_float32_uge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_uge_param_0];
+; CHECK-NEXT: setp.geu.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB13_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB13_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB13_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB13_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp uge float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp olt float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_ord(float %arg) {
+; CHECK-LABEL: test_float32_ord(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_ord_param_0];
+; CHECK-NEXT: setp.num.f32 %p1, %r1, %r1;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @!%p1 bra $L__BB14_1;
+; CHECK-NEXT: $L__BB14_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB14_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB14_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+; CHECK-NEXT: $L__BB14_1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: bra.uni $L__BB14_2;
+entry:
+ %cmp = fcmp ord float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp uno float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_uno(float %arg) {
+; CHECK-LABEL: test_float32_uno(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_uno_param_0];
+; CHECK-NEXT: setp.nan.f32 %p1, %r1, %r1;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB15_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB15_2: // %merge1
+; CHECK-NEXT: @%p1 bra $L__BB15_3;
+; CHECK-NEXT: $L__BB15_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+; CHECK-NEXT: $L__BB15_3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: bra.uni $L__BB15_4;
+entry:
+ %cmp = fcmp uno float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ord float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-float64.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-float64.ll
new file mode 100644
index 0000000000000..4106d7b9a9184
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-float64.ll
@@ -0,0 +1,679 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+; RUN: %if ptxas-sm_100 %{ llc < %s -march=nvptx64 -mcpu=sm_100 -O2 | %ptxas-verify -arch=sm_100 %}
+
+target triple = "nvptx64-nvidia-cuda"
+
+define i32 @test_float64_eq(double %arg) {
+; CHECK-LABEL: test_float64_eq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_eq_param_0];
+; CHECK-NEXT: setp.eq.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp une double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_ne(double %arg) {
+; CHECK-LABEL: test_float64_ne(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_ne_param_0];
+; CHECK-NEXT: setp.ne.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp one double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ueq double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_oeq(double %arg) {
+; CHECK-LABEL: test_float64_oeq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_oeq_param_0];
+; CHECK-NEXT: setp.eq.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB2_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB2_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB2_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB2_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp une double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_one(double %arg) {
+; CHECK-LABEL: test_float64_one(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_one_param_0];
+; CHECK-NEXT: setp.ne.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB3_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB3_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB3_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB3_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp one double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ueq double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_ueq(double %arg) {
+; CHECK-LABEL: test_float64_ueq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_ueq_param_0];
+; CHECK-NEXT: setp.equ.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB4_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB4_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB4_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB4_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ueq double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp one double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_une(double %arg) {
+; CHECK-LABEL: test_float64_une(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_une_param_0];
+; CHECK-NEXT: setp.neu.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB5_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB5_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB5_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB5_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp une double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp oeq double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_olt(double %arg) {
+; CHECK-LABEL: test_float64_olt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_olt_param_0];
+; CHECK-NEXT: setp.lt.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB6_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB6_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB6_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB6_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp olt double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp uge double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_ole(double %arg) {
+; CHECK-LABEL: test_float64_ole(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_ole_param_0];
+; CHECK-NEXT: setp.le.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB7_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB7_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB7_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB7_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ole double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ugt double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_ogt(double %arg) {
+; CHECK-LABEL: test_float64_ogt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_ogt_param_0];
+; CHECK-NEXT: setp.gt.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB8_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB8_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB8_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB8_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ogt double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ule double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_oge(double %arg) {
+; CHECK-LABEL: test_float64_oge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_oge_param_0];
+; CHECK-NEXT: setp.ge.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB9_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB9_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB9_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB9_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oge double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ult double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_ult(double %arg) {
+; CHECK-LABEL: test_float64_ult(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_ult_param_0];
+; CHECK-NEXT: setp.ltu.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB10_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB10_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB10_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB10_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ult double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp oge double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_ule(double %arg) {
+; CHECK-LABEL: test_float64_ule(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_ule_param_0];
+; CHECK-NEXT: setp.leu.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB11_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB11_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB11_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB11_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ule double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ogt double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_ugt(double %arg) {
+; CHECK-LABEL: test_float64_ugt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_ugt_param_0];
+; CHECK-NEXT: setp.gtu.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB12_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB12_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB12_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB12_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ugt double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ole double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_uge(double %arg) {
+; CHECK-LABEL: test_float64_uge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_uge_param_0];
+; CHECK-NEXT: setp.geu.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB13_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB13_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB13_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB13_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp uge double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp olt double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_ord(double %arg) {
+; CHECK-LABEL: test_float64_ord(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_ord_param_0];
+; CHECK-NEXT: setp.num.f64 %p1, %rd1, %rd1;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @!%p1 bra $L__BB14_1;
+; CHECK-NEXT: $L__BB14_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB14_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB14_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+; CHECK-NEXT: $L__BB14_1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: bra.uni $L__BB14_2;
+entry:
+ %cmp = fcmp ord double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp uno double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_uno(double %arg) {
+; CHECK-LABEL: test_float64_uno(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_uno_param_0];
+; CHECK-NEXT: setp.nan.f64 %p1, %rd1, %rd1;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB15_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB15_2: // %merge1
+; CHECK-NEXT: @%p1 bra $L__BB15_3;
+; CHECK-NEXT: $L__BB15_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+; CHECK-NEXT: $L__BB15_3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: bra.uni $L__BB15_4;
+entry:
+ %cmp = fcmp uno double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ord double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-int16.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-int16.ll
new file mode 100644
index 0000000000000..2cb3fa6110c18
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-int16.ll
@@ -0,0 +1,437 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+; RUN: %if ptxas-sm_100 %{ llc < %s -march=nvptx64 -mcpu=sm_100 -O2 | %ptxas-verify -arch=sm_100 %}
+
+target triple = "nvptx64-nvidia-cuda"
+
+; Test int16 integer comparison inversions
+
+define i32 @test_int16_eq(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_eq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_eq_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_eq_param_0];
+; CHECK-NEXT: setp.eq.b16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp eq i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ne i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int16_ne(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_ne(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_ne_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_ne_param_0];
+; CHECK-NEXT: setp.ne.b16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ne i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp eq i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int16_slt(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_slt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_slt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_slt_param_0];
+; CHECK-NEXT: setp.lt.s16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB2_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB2_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB2_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB2_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp slt i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sge i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int16_sle(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_sle(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_sle_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_sle_param_0];
+; CHECK-NEXT: setp.le.s16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB3_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB3_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB3_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB3_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp sle i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sgt i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int16_sgt(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_sgt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_sgt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_sgt_param_0];
+; CHECK-NEXT: setp.gt.s16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB4_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB4_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB4_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB4_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp sgt i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sle i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int16_sge(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_sge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_sge_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_sge_param_0];
+; CHECK-NEXT: setp.ge.s16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB5_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB5_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB5_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB5_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp sge i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp slt i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int16_ult(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_ult(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_ult_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_ult_param_0];
+; CHECK-NEXT: setp.lt.u16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB6_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB6_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB6_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB6_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ult i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp uge i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int16_ule(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_ule(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_ule_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_ule_param_0];
+; CHECK-NEXT: setp.le.u16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB7_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB7_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB7_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB7_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ule i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ugt i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int16_ugt(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_ugt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_ugt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_ugt_param_0];
+; CHECK-NEXT: setp.gt.u16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB8_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB8_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB8_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB8_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ugt i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ule i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int16_uge(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_uge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_uge_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_uge_param_0];
+; CHECK-NEXT: setp.ge.u16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB9_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB9_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB9_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB9_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp uge i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ult i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-int32.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-int32.ll
new file mode 100644
index 0000000000000..4d1f7c97fe594
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-int32.ll
@@ -0,0 +1,427 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+; RUN: %if ptxas-sm_100 %{ llc < %s -march=nvptx64 -mcpu=sm_100 -O2 | %ptxas-verify -arch=sm_100 %}
+
+target triple = "nvptx64-nvidia-cuda"
+
+; Test int32 integer comparison inversions
+
+define i32 @test_int32_eq(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_eq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_eq_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_eq_param_0];
+; CHECK-NEXT: setp.eq.b32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp eq i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ne i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int32_ne(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_ne(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_ne_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_ne_param_0];
+; CHECK-NEXT: setp.ne.b32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ne i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp eq i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int32_slt(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_slt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_slt_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_slt_param_0];
+; CHECK-NEXT: setp.lt.s32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB2_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB2_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB2_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB2_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp slt i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sge i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int32_sle(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_sle(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_sle_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_sle_param_0];
+; CHECK-NEXT: setp.le.s32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB3_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB3_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB3_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB3_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp sle i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sgt i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int32_sgt(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_sgt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_sgt_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_sgt_param_0];
+; CHECK-NEXT: setp.gt.s32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB4_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB4_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB4_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB4_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp sgt i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sle i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int32_sge(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_sge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_sge_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_sge_param_0];
+; CHECK-NEXT: setp.ge.s32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB5_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB5_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB5_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB5_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp sge i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp slt i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int32_ult(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_ult(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_ult_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_ult_param_0];
+; CHECK-NEXT: setp.lt.u32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB6_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB6_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB6_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB6_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ult i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp uge i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int32_ule(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_ule(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_ule_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_ule_param_0];
+; CHECK-NEXT: setp.le.u32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB7_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB7_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB7_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB7_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ule i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ugt i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int32_ugt(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_ugt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_ugt_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_ugt_param_0];
+; CHECK-NEXT: setp.gt.u32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB8_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB8_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB8_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB8_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ugt i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ule i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int32_uge(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_uge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_uge_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_uge_param_0];
+; CHECK-NEXT: setp.ge.u32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB9_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB9_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB9_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB9_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp uge i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ult i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-int64.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-int64.ll
new file mode 100644
index 0000000000000..bc90ea4335d2e
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-int64.ll
@@ -0,0 +1,437 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+; RUN: %if ptxas-sm_100 %{ llc < %s -march=nvptx64 -mcpu=sm_100 -O2 | %ptxas-verify -arch=sm_100 %}
+
+target triple = "nvptx64-nvidia-cuda"
+
+; Test int64 integer comparison inversions
+
+define i32 @test_int64_eq(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_eq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_eq_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_eq_param_0];
+; CHECK-NEXT: setp.eq.b64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp eq i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ne i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int64_ne(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_ne(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_ne_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_ne_param_0];
+; CHECK-NEXT: setp.ne.b64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ne i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp eq i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int64_slt(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_slt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_slt_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_slt_param_0];
+; CHECK-NEXT: setp.lt.s64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB2_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB2_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB2_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB2_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp slt i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sge i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int64_sle(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_sle(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_sle_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_sle_param_0];
+; CHECK-NEXT: setp.le.s64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB3_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB3_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB3_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB3_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp sle i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sgt i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int64_sgt(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_sgt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_sgt_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_sgt_param_0];
+; CHECK-NEXT: setp.gt.s64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB4_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB4_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB4_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB4_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp sgt i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sle i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int64_sge(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_sge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_sge_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_sge_param_0];
+; CHECK-NEXT: setp.ge.s64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB5_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB5_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB5_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB5_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp sge i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp slt i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int64_ult(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_ult(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_ult_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_ult_param_0];
+; CHECK-NEXT: setp.lt.u64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB6_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB6_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB6_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB6_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ult i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp uge i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int64_ule(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_ule(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_ule_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_ule_param_0];
+; CHECK-NEXT: setp.le.u64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB7_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB7_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB7_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB7_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ule i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ugt i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int64_ugt(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_ugt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_ugt_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_ugt_param_0];
+; CHECK-NEXT: setp.gt.u64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB8_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB8_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB8_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB8_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ugt i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ule i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int64_uge(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_uge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_uge_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_uge_param_0];
+; CHECK-NEXT: setp.ge.u64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB9_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB9_2: // %merge1
+; CHECK-NEXT: @!%p1 bra $L__BB9_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB9_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp uge i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ult i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-multiple-users.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-multiple-users.ll
new file mode 100644
index 0000000000000..bf4a77f599061
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-multiple-users.ll
@@ -0,0 +1,50 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+; RUN: %if ptxas-sm_100 %{ llc < %s -march=nvptx64 -mcpu=sm_100 -O2 | %ptxas-verify -arch=sm_100 %}
+
+target triple = "nvptx64-nvidia-cuda"
+
+define i32 @test_multiple_users(i32 %a, i32 %b) {
+; CHECK-LABEL: test_multiple_users(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b32 %r<6>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r3, [test_multiple_users_param_1];
+; CHECK-NEXT: ld.param.b32 %r2, [test_multiple_users_param_0];
+; CHECK-NEXT: setp.eq.b32 %p1, %r2, %r3;
+; CHECK-NEXT: mov.b32 %r5, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r5, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: selp.b32 %r1, 1, 0, %p1;
+; CHECK-NEXT: @!%p1 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r5, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: add.s32 %r4, %r5, %r1;
+; CHECK-NEXT: st.param.b32 [func_retval0], %r4;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp eq i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %val = select i1 %cmp, i32 1, i32 0
+ br i1 %cmp, label %else, label %merge2
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ %ret = add i32 %phi2, %val
+ ret i32 %ret
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-vector-float.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-vector-float.ll
new file mode 100644
index 0000000000000..a1e2301e54073
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-inversion-vector-float.ll
@@ -0,0 +1,99 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+; RUN: %if ptxas-sm_100 %{ llc < %s -march=nvptx64 -mcpu=sm_100 -O2 | %ptxas-verify -arch=sm_100 %}
+
+target triple = "nvptx64-nvidia-cuda"
+
+define i32 @test_float_f16x2_eq(i32 %arg) {
+; CHECK-LABEL: test_float_f16x2_eq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<5>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float_f16x2_eq_param_0];
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: setp.eq.f16x2 %p2|%p3, %r1, %r2;
+; CHECK-NEXT: and.pred %p1, %p2, %p3;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: not.pred %p4, %p1;
+; CHECK-NEXT: @%p4 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %a = bitcast i32 %arg to <2 x half>
+ %zero = bitcast i32 0 to <2 x half>
+ %cmp = fcmp oeq <2 x half> %a, %zero
+ %e0 = extractelement <2 x i1> %cmp, i32 0
+ %e1 = extractelement <2 x i1> %cmp, i32 1
+ %and = and i1 %e0, %e1
+ br i1 %and, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ br i1 %and, label %else, label %merge2
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float_bf16x2_eq(i32 %arg) {
+; CHECK-LABEL: test_float_bf16x2_eq(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<5>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float_bf16x2_eq_param_0];
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: setp.eq.bf16x2 %p2|%p3, %r1, %r2;
+; CHECK-NEXT: and.pred %p1, %p2, %p3;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: not.pred %p4, %p1;
+; CHECK-NEXT: @%p4 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %a = bitcast i32 %arg to <2 x bfloat>
+ %zero = bitcast i32 0 to <2 x bfloat>
+ %cmp = fcmp oeq <2 x bfloat> %a, %zero
+ %e0 = extractelement <2 x i1> %cmp, i32 0
+ %e1 = extractelement <2 x i1> %cmp, i32 1
+ %and = and i1 %e0, %e1
+ br i1 %and, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ br i1 %and, label %else, label %merge2
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-bfloat16.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-bfloat16.ll
new file mode 100644
index 0000000000000..9e966e1843811
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-bfloat16.ll
@@ -0,0 +1,224 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+
+target triple = "nvptx64-nvidia-cuda"
+
+define i32 @test_bfloat16_ueq_vs_une(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_ueq_vs_une(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_ueq_vs_une_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_ueq_vs_une_param_0];
+; CHECK-NEXT: setp.equ.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: setp.neu.bf16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ueq bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp une bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_oeq_vs_one(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_oeq_vs_one(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_oeq_vs_one_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_oeq_vs_one_param_0];
+; CHECK-NEXT: setp.eq.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: setp.ne.bf16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp one bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_olt_vs_ogt(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_olt_vs_ogt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_olt_vs_ogt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_olt_vs_ogt_param_0];
+; CHECK-NEXT: setp.lt.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB2_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB2_2: // %merge1
+; CHECK-NEXT: setp.gt.bf16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB2_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB2_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp olt bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ogt bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_ult_vs_ugt(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_ult_vs_ugt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_ult_vs_ugt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_ult_vs_ugt_param_0];
+; CHECK-NEXT: setp.ltu.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB3_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB3_2: // %merge1
+; CHECK-NEXT: setp.gtu.bf16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB3_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB3_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ult bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ugt bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_bfloat16_oeq_vs_olt(bfloat %a, bfloat %b) {
+; CHECK-LABEL: test_bfloat16_oeq_vs_olt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_bfloat16_oeq_vs_olt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_bfloat16_oeq_vs_olt_param_0];
+; CHECK-NEXT: setp.eq.bf16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB4_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB4_2: // %merge1
+; CHECK-NEXT: setp.lt.bf16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB4_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB4_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq bfloat %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp olt bfloat %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-float16.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-float16.ll
new file mode 100644
index 0000000000000..6ea217ab97b53
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-float16.ll
@@ -0,0 +1,224 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+
+target triple = "nvptx64-nvidia-cuda"
+
+define i32 @test_float16_ueq_vs_une(half %a, half %b) {
+; CHECK-LABEL: test_float16_ueq_vs_une(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_ueq_vs_une_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_ueq_vs_une_param_0];
+; CHECK-NEXT: setp.equ.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: setp.neu.f16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ueq half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp une half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_oeq_vs_one(half %a, half %b) {
+; CHECK-LABEL: test_float16_oeq_vs_one(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_oeq_vs_one_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_oeq_vs_one_param_0];
+; CHECK-NEXT: setp.eq.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: setp.ne.f16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp one half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_olt_vs_ogt(half %a, half %b) {
+; CHECK-LABEL: test_float16_olt_vs_ogt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_olt_vs_ogt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_olt_vs_ogt_param_0];
+; CHECK-NEXT: setp.lt.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB2_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB2_2: // %merge1
+; CHECK-NEXT: setp.gt.f16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB2_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB2_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp olt half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ogt half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_ult_vs_ugt(half %a, half %b) {
+; CHECK-LABEL: test_float16_ult_vs_ugt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_ult_vs_ugt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_ult_vs_ugt_param_0];
+; CHECK-NEXT: setp.ltu.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB3_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB3_2: // %merge1
+; CHECK-NEXT: setp.gtu.f16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB3_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB3_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ult half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ugt half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float16_oeq_vs_olt(half %a, half %b) {
+; CHECK-LABEL: test_float16_oeq_vs_olt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_float16_oeq_vs_olt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_float16_oeq_vs_olt_param_0];
+; CHECK-NEXT: setp.eq.f16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB4_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB4_2: // %merge1
+; CHECK-NEXT: setp.lt.f16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB4_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB4_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq half %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp olt half %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-float32.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-float32.ll
new file mode 100644
index 0000000000000..9008782b70b25
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-float32.ll
@@ -0,0 +1,214 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+
+target triple = "nvptx64-nvidia-cuda"
+
+define i32 @test_float32_ueq_vs_une(float %arg) {
+; CHECK-LABEL: test_float32_ueq_vs_une(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_ueq_vs_une_param_0];
+; CHECK-NEXT: setp.equ.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: setp.neu.f32 %p2, %r1, 0f00000000;
+; CHECK-NEXT: @%p2 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ueq float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp une float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_oeq_vs_one(float %arg) {
+; CHECK-LABEL: test_float32_oeq_vs_one(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_oeq_vs_one_param_0];
+; CHECK-NEXT: setp.eq.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: setp.ne.f32 %p2, %r1, 0f00000000;
+; CHECK-NEXT: @%p2 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp one float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_olt_vs_ogt(float %arg) {
+; CHECK-LABEL: test_float32_olt_vs_ogt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_olt_vs_ogt_param_0];
+; CHECK-NEXT: setp.lt.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB2_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB2_2: // %merge1
+; CHECK-NEXT: setp.gt.f32 %p2, %r1, 0f00000000;
+; CHECK-NEXT: @%p2 bra $L__BB2_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB2_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp olt float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ogt float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_ult_vs_ugt(float %arg) {
+; CHECK-LABEL: test_float32_ult_vs_ugt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_ult_vs_ugt_param_0];
+; CHECK-NEXT: setp.ltu.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB3_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB3_2: // %merge1
+; CHECK-NEXT: setp.gtu.f32 %p2, %r1, 0f00000000;
+; CHECK-NEXT: @%p2 bra $L__BB3_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB3_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ult float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ugt float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float32_oeq_vs_olt(float %arg) {
+; CHECK-LABEL: test_float32_oeq_vs_olt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r1, [test_float32_oeq_vs_olt_param_0];
+; CHECK-NEXT: setp.eq.f32 %p1, %r1, 0f00000000;
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: @%p1 bra $L__BB4_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r2, 1;
+; CHECK-NEXT: $L__BB4_2: // %merge1
+; CHECK-NEXT: setp.lt.f32 %p2, %r1, 0f00000000;
+; CHECK-NEXT: @%p2 bra $L__BB4_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r2, 0;
+; CHECK-NEXT: $L__BB4_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r2;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq float %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp olt float %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-float64.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-float64.ll
new file mode 100644
index 0000000000000..1c6ab1ef6f093
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-float64.ll
@@ -0,0 +1,219 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+
+target triple = "nvptx64-nvidia-cuda"
+
+define i32 @test_float64_ueq_vs_une(double %arg) {
+; CHECK-LABEL: test_float64_ueq_vs_une(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_ueq_vs_une_param_0];
+; CHECK-NEXT: setp.equ.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: setp.neu.f64 %p2, %rd1, 0d0000000000000000;
+; CHECK-NEXT: @%p2 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ueq double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp une double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_oeq_vs_one(double %arg) {
+; CHECK-LABEL: test_float64_oeq_vs_one(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_oeq_vs_one_param_0];
+; CHECK-NEXT: setp.eq.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: setp.ne.f64 %p2, %rd1, 0d0000000000000000;
+; CHECK-NEXT: @%p2 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp one double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_olt_vs_ogt(double %arg) {
+; CHECK-LABEL: test_float64_olt_vs_ogt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_olt_vs_ogt_param_0];
+; CHECK-NEXT: setp.lt.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB2_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB2_2: // %merge1
+; CHECK-NEXT: setp.gt.f64 %p2, %rd1, 0d0000000000000000;
+; CHECK-NEXT: @%p2 bra $L__BB2_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB2_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp olt double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ogt double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_ult_vs_ugt(double %arg) {
+; CHECK-LABEL: test_float64_ult_vs_ugt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_ult_vs_ugt_param_0];
+; CHECK-NEXT: setp.ltu.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB3_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB3_2: // %merge1
+; CHECK-NEXT: setp.gtu.f64 %p2, %rd1, 0d0000000000000000;
+; CHECK-NEXT: @%p2 bra $L__BB3_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB3_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp ult double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp ugt double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_float64_oeq_vs_olt(double %arg) {
+; CHECK-LABEL: test_float64_oeq_vs_olt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd1, [test_float64_oeq_vs_olt_param_0];
+; CHECK-NEXT: setp.eq.f64 %p1, %rd1, 0d0000000000000000;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB4_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB4_2: // %merge1
+; CHECK-NEXT: setp.lt.f64 %p2, %rd1, 0d0000000000000000;
+; CHECK-NEXT: @%p2 bra $L__BB4_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB4_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = fcmp oeq double %arg, 0.000000e+00
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = fcmp olt double %arg, 0.000000e+00
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-int16.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-int16.ll
new file mode 100644
index 0000000000000..e9656967225e3
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-int16.ll
@@ -0,0 +1,224 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+
+target triple = "nvptx64-nvidia-cuda"
+
+define i32 @test_int16_slt_vs_sgt(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_slt_vs_sgt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_slt_vs_sgt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_slt_vs_sgt_param_0];
+; CHECK-NEXT: setp.lt.s16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: setp.gt.s16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp slt i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sgt i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int16_ult_vs_ugt(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_ult_vs_ugt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_ult_vs_ugt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_ult_vs_ugt_param_0];
+; CHECK-NEXT: setp.lt.u16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: setp.gt.u16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ult i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ugt i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int16_slt_vs_uge(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_slt_vs_uge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_slt_vs_uge_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_slt_vs_uge_param_0];
+; CHECK-NEXT: setp.lt.s16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB2_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB2_2: // %merge1
+; CHECK-NEXT: setp.ge.u16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB2_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB2_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp slt i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp uge i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int16_eq_vs_slt(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_eq_vs_slt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_eq_vs_slt_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_eq_vs_slt_param_0];
+; CHECK-NEXT: setp.eq.b16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB3_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB3_2: // %merge1
+; CHECK-NEXT: setp.lt.s16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB3_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB3_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp eq i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp slt i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int16_ult_vs_sge(i16 %a, i16 %b) {
+; CHECK-LABEL: test_int16_ult_vs_sge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b16 %rs<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b16 %rs2, [test_int16_ult_vs_sge_param_1];
+; CHECK-NEXT: ld.param.b16 %rs1, [test_int16_ult_vs_sge_param_0];
+; CHECK-NEXT: setp.lt.u16 %p1, %rs1, %rs2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB4_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB4_2: // %merge1
+; CHECK-NEXT: setp.ge.s16 %p2, %rs1, %rs2;
+; CHECK-NEXT: @%p2 bra $L__BB4_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB4_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ult i16 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sge i16 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-int32.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-int32.ll
new file mode 100644
index 0000000000000..3820ea527dc05
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-int32.ll
@@ -0,0 +1,219 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+
+target triple = "nvptx64-nvidia-cuda"
+
+define i32 @test_int32_slt_vs_sgt(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_slt_vs_sgt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_slt_vs_sgt_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_slt_vs_sgt_param_0];
+; CHECK-NEXT: setp.lt.s32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: setp.gt.s32 %p2, %r1, %r2;
+; CHECK-NEXT: @%p2 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp slt i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sgt i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int32_ult_vs_ugt(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_ult_vs_ugt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_ult_vs_ugt_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_ult_vs_ugt_param_0];
+; CHECK-NEXT: setp.lt.u32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: setp.gt.u32 %p2, %r1, %r2;
+; CHECK-NEXT: @%p2 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ult i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ugt i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int32_slt_vs_uge(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_slt_vs_uge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_slt_vs_uge_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_slt_vs_uge_param_0];
+; CHECK-NEXT: setp.lt.s32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB2_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB2_2: // %merge1
+; CHECK-NEXT: setp.ge.u32 %p2, %r1, %r2;
+; CHECK-NEXT: @%p2 bra $L__BB2_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB2_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp slt i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp uge i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int32_eq_vs_slt(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_eq_vs_slt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_eq_vs_slt_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_eq_vs_slt_param_0];
+; CHECK-NEXT: setp.eq.b32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB3_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB3_2: // %merge1
+; CHECK-NEXT: setp.lt.s32 %p2, %r1, %r2;
+; CHECK-NEXT: @%p2 bra $L__BB3_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB3_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp eq i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp slt i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int32_ult_vs_sge(i32 %a, i32 %b) {
+; CHECK-LABEL: test_int32_ult_vs_sge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<4>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b32 %r2, [test_int32_ult_vs_sge_param_1];
+; CHECK-NEXT: ld.param.b32 %r1, [test_int32_ult_vs_sge_param_0];
+; CHECK-NEXT: setp.lt.u32 %p1, %r1, %r2;
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: @%p1 bra $L__BB4_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r3, 1;
+; CHECK-NEXT: $L__BB4_2: // %merge1
+; CHECK-NEXT: setp.ge.s32 %p2, %r1, %r2;
+; CHECK-NEXT: @%p2 bra $L__BB4_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r3, 0;
+; CHECK-NEXT: $L__BB4_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r3;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ult i32 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sge i32 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
diff --git a/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-int64.ll b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-int64.ll
new file mode 100644
index 0000000000000..9989929f8f5db
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/machine-cse-predicate-no-inversion-int64.ll
@@ -0,0 +1,224 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=nvptx64 -mcpu=sm_100 -O2 < %s | FileCheck %s
+
+target triple = "nvptx64-nvidia-cuda"
+
+define i32 @test_int64_slt_vs_sgt(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_slt_vs_sgt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_slt_vs_sgt_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_slt_vs_sgt_param_0];
+; CHECK-NEXT: setp.lt.s64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB0_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB0_2: // %merge1
+; CHECK-NEXT: setp.gt.s64 %p2, %rd1, %rd2;
+; CHECK-NEXT: @%p2 bra $L__BB0_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB0_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp slt i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sgt i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int64_ult_vs_ugt(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_ult_vs_ugt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_ult_vs_ugt_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_ult_vs_ugt_param_0];
+; CHECK-NEXT: setp.lt.u64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB1_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB1_2: // %merge1
+; CHECK-NEXT: setp.gt.u64 %p2, %rd1, %rd2;
+; CHECK-NEXT: @%p2 bra $L__BB1_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB1_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ult i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp ugt i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int64_slt_vs_uge(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_slt_vs_uge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_slt_vs_uge_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_slt_vs_uge_param_0];
+; CHECK-NEXT: setp.lt.s64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB2_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB2_2: // %merge1
+; CHECK-NEXT: setp.ge.u64 %p2, %rd1, %rd2;
+; CHECK-NEXT: @%p2 bra $L__BB2_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB2_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp slt i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp uge i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int64_eq_vs_slt(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_eq_vs_slt(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_eq_vs_slt_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_eq_vs_slt_param_0];
+; CHECK-NEXT: setp.eq.b64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB3_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB3_2: // %merge1
+; CHECK-NEXT: setp.lt.s64 %p2, %rd1, %rd2;
+; CHECK-NEXT: @%p2 bra $L__BB3_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB3_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp eq i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp slt i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
+
+define i32 @test_int64_ult_vs_sge(i64 %a, i64 %b) {
+; CHECK-LABEL: test_int64_ult_vs_sge(
+; CHECK: {
+; CHECK-NEXT: .reg .pred %p<3>;
+; CHECK-NEXT: .reg .b32 %r<2>;
+; CHECK-NEXT: .reg .b64 %rd<3>;
+; CHECK-EMPTY:
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: ld.param.b64 %rd2, [test_int64_ult_vs_sge_param_1];
+; CHECK-NEXT: ld.param.b64 %rd1, [test_int64_ult_vs_sge_param_0];
+; CHECK-NEXT: setp.lt.u64 %p1, %rd1, %rd2;
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: @%p1 bra $L__BB4_2;
+; CHECK-NEXT: // %bb.1: // %then
+; CHECK-NEXT: mov.b32 %r1, 1;
+; CHECK-NEXT: $L__BB4_2: // %merge1
+; CHECK-NEXT: setp.ge.s64 %p2, %rd1, %rd2;
+; CHECK-NEXT: @%p2 bra $L__BB4_4;
+; CHECK-NEXT: // %bb.3: // %else
+; CHECK-NEXT: mov.b32 %r1, 0;
+; CHECK-NEXT: $L__BB4_4: // %merge2
+; CHECK-NEXT: st.param.b32 [func_retval0], %r1;
+; CHECK-NEXT: ret;
+entry:
+ %cmp = icmp ult i64 %a, %b
+ br i1 %cmp, label %merge1, label %then
+
+then:
+ %tmp = load i32, ptr addrspace(1) null, align 4
+ br label %merge1
+
+merge1:
+ %phi1 = phi i32 [ 1, %then ], [ 0, %entry ]
+ %cmp2 = icmp sge i64 %a, %b
+ br i1 %cmp2, label %merge2, label %else
+
+else:
+ br label %merge2
+
+merge2:
+ %phi2 = phi i32 [ %phi1, %merge1 ], [ 0, %else ]
+ ret i32 %phi2
+}
More information about the llvm-commits
mailing list