[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