File backport-llvm-r196578 of Package llvm

------------------------------------------------------------------------
r196578 | rsandifo | 2013-12-06 10:53:09 +0100 (Fri, 06 Dec 2013) | 11 lines

[SystemZ] Optimize selects between 0 and -1

Since z has no setcc instruction as such, the choice of setBooleanContents
is a bit arbitrary.  Currently it's set to ZeroOrOneBooleanContent,
so we produced a branch-free form when selecting between 0 and 1,
but not when selecting between 0 and -1.  This patch handles the latter
case too.

At some point I'd like to measure whether it's better to use conditional
moves for constant selects on z196, but that's future work.

------------------------------------------------------------------------
Index: lib/Target/SystemZ/SystemZISelLowering.cpp
===================================================================
--- lib/Target/SystemZ/SystemZISelLowering.cpp.orig
+++ lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -1486,16 +1486,11 @@ static void lowerGR128Binary(SelectionDA
   Odd = DAG.getTargetExtractSubreg(SystemZ::odd128(Is32Bit), DL, VT, Result);
 }
 
-SDValue SystemZTargetLowering::lowerSETCC(SDValue Op,
-                                          SelectionDAG &DAG) const {
-  SDValue CmpOp0   = Op.getOperand(0);
-  SDValue CmpOp1   = Op.getOperand(1);
-  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
-  SDLoc DL(Op);
-
-  unsigned CCValid, CCMask;
-  SDValue Glue = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask);
-
+// Return an i32 value that is 1 if the CC value produced by Glue is
+// in the mask CCMask and 0 otherwise.  CC is known to have a value
+// in CCValid, so other values can be ignored.
+static SDValue emitSETCC(SelectionDAG &DAG, SDLoc DL, SDValue Glue,
+                         unsigned CCValid, unsigned CCMask) {
   IPMConversion Conversion = getIPMConversion(CCValid, CCMask);
   SDValue Result = DAG.getNode(SystemZISD::IPM, DL, MVT::i32, Glue);
 
@@ -1516,6 +1511,18 @@ SDValue SystemZTargetLowering::lowerSETC
   return Result;
 }
 
+SDValue SystemZTargetLowering::lowerSETCC(SDValue Op,
+                                          SelectionDAG &DAG) const {
+  SDValue CmpOp0   = Op.getOperand(0);
+  SDValue CmpOp1   = Op.getOperand(1);
+  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
+  SDLoc DL(Op);
+
+  unsigned CCValid, CCMask;
+  SDValue Glue = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask);
+  return emitSETCC(DAG, DL, Glue, CCValid, CCMask);
+}
+
 SDValue SystemZTargetLowering::lowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
   SDValue Chain    = Op.getOperand(0);
   ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
@@ -1525,10 +1532,10 @@ SDValue SystemZTargetLowering::lowerBR_C
   SDLoc DL(Op);
 
   unsigned CCValid, CCMask;
-  SDValue Flags = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask);
+  SDValue Glue = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask);
   return DAG.getNode(SystemZISD::BR_CCMASK, DL, Op.getValueType(),
                      Chain, DAG.getConstant(CCValid, MVT::i32),
-                     DAG.getConstant(CCMask, MVT::i32), Dest, Flags);
+                     DAG.getConstant(CCMask, MVT::i32), Dest, Glue);
 }
 
 SDValue SystemZTargetLowering::lowerSELECT_CC(SDValue Op,
@@ -1541,14 +1548,37 @@ SDValue SystemZTargetLowering::lowerSELE
   SDLoc DL(Op);
 
   unsigned CCValid, CCMask;
-  SDValue Flags = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask);
+  SDValue Glue = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask);
+
+  // Special case for handling -1/0 results.  The shifts we use here
+  // should get optimized with the IPM conversion sequence.
+  ConstantSDNode *TrueC = dyn_cast<ConstantSDNode>(TrueOp);
+  ConstantSDNode *FalseC = dyn_cast<ConstantSDNode>(FalseOp);
+  if (TrueC && FalseC) {
+    int64_t TrueVal = TrueC->getSExtValue();
+    int64_t FalseVal = FalseC->getSExtValue();
+    if ((TrueVal == -1 && FalseVal == 0) || (TrueVal == 0 && FalseVal == -1)) {
+      // Invert the condition if we want -1 on false.
+      if (TrueVal == 0)
+        CCMask ^= CCValid;
+      SDValue Result = emitSETCC(DAG, DL, Glue, CCValid, CCMask);
+      EVT VT = Op.getValueType();
+      // Extend the result to VT.  Upper bits are ignored.
+      if (!is32Bit(VT))
+        Result = DAG.getNode(ISD::ANY_EXTEND, DL, VT, Result);
+      // Sign-extend from the low bit.
+      SDValue ShAmt = DAG.getConstant(VT.getSizeInBits() - 1, MVT::i32);
+      SDValue Shl = DAG.getNode(ISD::SHL, DL, VT, Result, ShAmt);
+      return DAG.getNode(ISD::SRA, DL, VT, Shl, ShAmt);
+    }
+  }
 
   SmallVector<SDValue, 5> Ops;
   Ops.push_back(TrueOp);
   Ops.push_back(FalseOp);
   Ops.push_back(DAG.getConstant(CCValid, MVT::i32));
   Ops.push_back(DAG.getConstant(CCMask, MVT::i32));
-  Ops.push_back(Flags);
+  Ops.push_back(Glue);
 
   SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
   return DAG.getNode(SystemZISD::SELECT_CCMASK, DL, VTs, &Ops[0], Ops.size());
Index: test/CodeGen/SystemZ/selectcc-01.ll
===================================================================
--- /dev/null
+++ test/CodeGen/SystemZ/selectcc-01.ll
@@ -0,0 +1,178 @@
+; Test an i32 0/-1 SELECTCCC for every floating-point condition.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+
+; Test CC in { 0 }
+define i32 @f1(float %a, float %b) {
+; CHECK-LABEL: f1:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -268435456
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp oeq float %a, %b
+  %res = select i1 %cond, i32 -1, i32 0
+  ret i32 %res
+}
+
+; Test CC in { 1 }
+define i32 @f2(float %a, float %b) {
+; CHECK-LABEL: f2:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, -268435456
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp olt float %a, %b
+  %res = select i1 %cond, i32 -1, i32 0
+  ret i32 %res
+}
+
+; Test CC in { 0, 1 }
+define i32 @f3(float %a, float %b) {
+; CHECK-LABEL: f3:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -536870912
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp ole float %a, %b
+  %res = select i1 %cond, i32 -1, i32 0
+  ret i32 %res
+}
+
+; Test CC in { 2 }
+define i32 @f4(float %a, float %b) {
+; CHECK-LABEL: f4:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, 1342177280
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp ogt float %a, %b
+  %res = select i1 %cond, i32 -1, i32 0
+  ret i32 %res
+}
+
+; Test CC in { 0, 2 }
+define i32 @f5(float %a, float %b) {
+; CHECK-LABEL: f5:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 4294967295
+; CHECK-NEXT: sll %r2, 3
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp oge float %a, %b
+  %res = select i1 %cond, i32 -1, i32 0
+  ret i32 %res
+}
+
+; Test CC in { 1, 2 }
+define i32 @f6(float %a, float %b) {
+; CHECK-LABEL: f6:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, 268435456
+; CHECK-NEXT: sll %r2, 2
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp one float %a, %b
+  %res = select i1 %cond, i32 -1, i32 0
+  ret i32 %res
+}
+
+; Test CC in { 0, 1, 2 }
+define i32 @f7(float %a, float %b) {
+; CHECK-LABEL: f7:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -805306368
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp ord float %a, %b
+  %res = select i1 %cond, i32 -1, i32 0
+  ret i32 %res
+}
+
+; Test CC in { 3 }
+define i32 @f8(float %a, float %b) {
+; CHECK-LABEL: f8:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, 1342177280
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp uno float %a, %b
+  %res = select i1 %cond, i32 -1, i32 0
+  ret i32 %res
+}
+
+; Test CC in { 0, 3 }
+define i32 @f9(float %a, float %b) {
+; CHECK-LABEL: f9:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -268435456
+; CHECK-NEXT: sll %r2, 2
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp ueq float %a, %b
+  %res = select i1 %cond, i32 -1, i32 0
+  ret i32 %res
+}
+
+; Test CC in { 1, 3 }
+define i32 @f10(float %a, float %b) {
+; CHECK-LABEL: f10:
+; CHECK: ipm %r2
+; CHECK-NEXT: sll %r2, 3
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp ult float %a, %b
+  %res = select i1 %cond, i32 -1, i32 0
+  ret i32 %res
+}
+
+; Test CC in { 0, 1, 3 }
+define i32 @f11(float %a, float %b) {
+; CHECK-LABEL: f11:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, -805306368
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp ule float %a, %b
+  %res = select i1 %cond, i32 -1, i32 0
+  ret i32 %res
+}
+
+; Test CC in { 2, 3 }
+define i32 @f12(float %a, float %b) {
+; CHECK-LABEL: f12:
+; CHECK: ipm %r2
+; CHECK-NEXT: sll %r2, 2
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp ugt float %a, %b
+  %res = select i1 %cond, i32 -1, i32 0
+  ret i32 %res
+}
+
+; Test CC in { 0, 2, 3 }
+define i32 @f13(float %a, float %b) {
+; CHECK-LABEL: f13:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, 1879048192
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp uge float %a, %b
+  %res = select i1 %cond, i32 -1, i32 0
+  ret i32 %res
+}
+
+; Test CC in { 1, 2, 3 }
+define i32 @f14(float %a, float %b) {
+; CHECK-LABEL: f14:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, 1879048192
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp une float %a, %b
+  %res = select i1 %cond, i32 -1, i32 0
+  ret i32 %res
+}
Index: test/CodeGen/SystemZ/selectcc-02.ll
===================================================================
--- /dev/null
+++ test/CodeGen/SystemZ/selectcc-02.ll
@@ -0,0 +1,178 @@
+; Test an i32 0/-1 SELECTCCC for every floating-point condition.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+
+; Test CC in { 1, 2, 3 }
+define i32 @f1(float %a, float %b) {
+; CHECK-LABEL: f1:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, 1879048192
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp oeq float %a, %b
+  %res = select i1 %cond, i32 0, i32 -1
+  ret i32 %res
+}
+
+; Test CC in { 0, 2, 3 }
+define i32 @f2(float %a, float %b) {
+; CHECK-LABEL: f2:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, 1879048192
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp olt float %a, %b
+  %res = select i1 %cond, i32 0, i32 -1
+  ret i32 %res
+}
+
+; Test CC in { 2, 3 }
+define i32 @f3(float %a, float %b) {
+; CHECK-LABEL: f3:
+; CHECK: ipm %r2
+; CHECK-NEXT: sll %r2, 2
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp ole float %a, %b
+  %res = select i1 %cond, i32 0, i32 -1
+  ret i32 %res
+}
+
+; Test CC in { 0, 1, 3 }
+define i32 @f4(float %a, float %b) {
+; CHECK-LABEL: f4:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, -805306368
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp ogt float %a, %b
+  %res = select i1 %cond, i32 0, i32 -1
+  ret i32 %res
+}
+
+; Test CC in { 1, 3 }
+define i32 @f5(float %a, float %b) {
+; CHECK-LABEL: f5:
+; CHECK: ipm %r2
+; CHECK-NEXT: sll %r2, 3
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp oge float %a, %b
+  %res = select i1 %cond, i32 0, i32 -1
+  ret i32 %res
+}
+
+; Test CC in { 0, 3 }
+define i32 @f6(float %a, float %b) {
+; CHECK-LABEL: f6:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -268435456
+; CHECK-NEXT: sll %r2, 2
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp one float %a, %b
+  %res = select i1 %cond, i32 0, i32 -1
+  ret i32 %res
+}
+
+; Test CC in { 3 }
+define i32 @f7(float %a, float %b) {
+; CHECK-LABEL: f7:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, 1342177280
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp ord float %a, %b
+  %res = select i1 %cond, i32 0, i32 -1
+  ret i32 %res
+}
+
+; Test CC in { 0, 1, 2 }
+define i32 @f8(float %a, float %b) {
+; CHECK-LABEL: f8:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -805306368
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp uno float %a, %b
+  %res = select i1 %cond, i32 0, i32 -1
+  ret i32 %res
+}
+
+; Test CC in { 1, 2 }
+define i32 @f9(float %a, float %b) {
+; CHECK-LABEL: f9:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, 268435456
+; CHECK-NEXT: sll %r2, 2
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp ueq float %a, %b
+  %res = select i1 %cond, i32 0, i32 -1
+  ret i32 %res
+}
+
+; Test CC in { 0, 2 }
+define i32 @f10(float %a, float %b) {
+; CHECK-LABEL: f10:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 4294967295
+; CHECK-NEXT: sll %r2, 3
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp ult float %a, %b
+  %res = select i1 %cond, i32 0, i32 -1
+  ret i32 %res
+}
+
+; Test CC in { 2 }
+define i32 @f11(float %a, float %b) {
+; CHECK-LABEL: f11:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, 1342177280
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp ule float %a, %b
+  %res = select i1 %cond, i32 0, i32 -1
+  ret i32 %res
+}
+
+; Test CC in { 0, 1 }
+define i32 @f12(float %a, float %b) {
+; CHECK-LABEL: f12:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -536870912
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp ugt float %a, %b
+  %res = select i1 %cond, i32 0, i32 -1
+  ret i32 %res
+}
+
+; Test CC in { 1 }
+define i32 @f13(float %a, float %b) {
+; CHECK-LABEL: f13:
+; CHECK: ipm %r2
+; CHECK-NEXT: xilf %r2, 268435456
+; CHECK-NEXT: afi %r2, -268435456
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp uge float %a, %b
+  %res = select i1 %cond, i32 0, i32 -1
+  ret i32 %res
+}
+
+; Test CC in { 0 }
+define i32 @f14(float %a, float %b) {
+; CHECK-LABEL: f14:
+; CHECK: ipm %r2
+; CHECK-NEXT: afi %r2, -268435456
+; CHECK-NEXT: sra %r2, 31
+; CHECK: br %r14
+  %cond = fcmp une float %a, %b
+  %res = select i1 %cond, i32 0, i32 -1
+  ret i32 %res
+}
Index: test/CodeGen/SystemZ/selectcc-03.ll
===================================================================
--- /dev/null
+++ test/CodeGen/SystemZ/selectcc-03.ll
@@ -0,0 +1,187 @@
+; Test an i64 0/-1 SELECTCCC for every floating-point condition.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+
+; Test CC in { 0 }
+define i64 @f1(float %a, float %b) {
+; CHECK-LABEL: f1:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: afi [[REG]], -268435456
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+  %cond = fcmp oeq float %a, %b
+  %res = select i1 %cond, i64 -1, i64 0
+  ret i64 %res
+}
+
+; Test CC in { 1 }
+define i64 @f2(float %a, float %b) {
+; CHECK-LABEL: f2:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: xilf [[REG]], 268435456
+; CHECK-NEXT: afi [[REG]], -268435456
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+  %cond = fcmp olt float %a, %b
+  %res = select i1 %cond, i64 -1, i64 0
+  ret i64 %res
+}
+
+; Test CC in { 0, 1 }
+define i64 @f3(float %a, float %b) {
+; CHECK-LABEL: f3:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: afi [[REG]], -536870912
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+  %cond = fcmp ole float %a, %b
+  %res = select i1 %cond, i64 -1, i64 0
+  ret i64 %res
+}
+
+; Test CC in { 2 }
+define i64 @f4(float %a, float %b) {
+; CHECK-LABEL: f4:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: xilf [[REG]], 268435456
+; CHECK-NEXT: afi [[REG]], 1342177280
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+  %cond = fcmp ogt float %a, %b
+  %res = select i1 %cond, i64 -1, i64 0
+  ret i64 %res
+}
+
+; Test CC in { 0, 2 }
+define i64 @f5(float %a, float %b) {
+; CHECK-LABEL: f5:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: xilf [[REG]], 4294967295
+; CHECK-NEXT: sllg [[REG]], [[REG]], 35
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+  %cond = fcmp oge float %a, %b
+  %res = select i1 %cond, i64 -1, i64 0
+  ret i64 %res
+}
+
+; Test CC in { 1, 2 }
+define i64 @f6(float %a, float %b) {
+; CHECK-LABEL: f6:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: afi [[REG]], 268435456
+; CHECK-NEXT: sllg [[REG]], [[REG]], 34
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+  %cond = fcmp one float %a, %b
+  %res = select i1 %cond, i64 -1, i64 0
+  ret i64 %res
+}
+
+; Test CC in { 0, 1, 2 }
+define i64 @f7(float %a, float %b) {
+; CHECK-LABEL: f7:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: afi [[REG]], -805306368
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+  %cond = fcmp ord float %a, %b
+  %res = select i1 %cond, i64 -1, i64 0
+  ret i64 %res
+}
+
+; Test CC in { 3 }
+define i64 @f8(float %a, float %b) {
+; CHECK-LABEL: f8:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: afi [[REG]], 1342177280
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+  %cond = fcmp uno float %a, %b
+  %res = select i1 %cond, i64 -1, i64 0
+  ret i64 %res
+}
+
+; Test CC in { 0, 3 }
+define i64 @f9(float %a, float %b) {
+; CHECK-LABEL: f9:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: afi [[REG]], -268435456
+; CHECK-NEXT: sllg [[REG]], [[REG]], 34
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+  %cond = fcmp ueq float %a, %b
+  %res = select i1 %cond, i64 -1, i64 0
+  ret i64 %res
+}
+
+; Test CC in { 1, 3 }
+define i64 @f10(float %a, float %b) {
+; CHECK-LABEL: f10:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: sllg [[REG]], [[REG]], 35
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+  %cond = fcmp ult float %a, %b
+  %res = select i1 %cond, i64 -1, i64 0
+  ret i64 %res
+}
+
+; Test CC in { 0, 1, 3 }
+define i64 @f11(float %a, float %b) {
+; CHECK-LABEL: f11:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: xilf [[REG]], 268435456
+; CHECK-NEXT: afi [[REG]], -805306368
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+  %cond = fcmp ule float %a, %b
+  %res = select i1 %cond, i64 -1, i64 0
+  ret i64 %res
+}
+
+; Test CC in { 2, 3 }
+define i64 @f12(float %a, float %b) {
+; CHECK-LABEL: f12:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: sllg [[REG]], [[REG]], 34
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+  %cond = fcmp ugt float %a, %b
+  %res = select i1 %cond, i64 -1, i64 0
+  ret i64 %res
+}
+
+; Test CC in { 0, 2, 3 }
+define i64 @f13(float %a, float %b) {
+; CHECK-LABEL: f13:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: xilf [[REG]], 268435456
+; CHECK-NEXT: afi [[REG]], 1879048192
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+  %cond = fcmp uge float %a, %b
+  %res = select i1 %cond, i64 -1, i64 0
+  ret i64 %res
+}
+
+; Test CC in { 1, 2, 3 }
+define i64 @f14(float %a, float %b) {
+; CHECK-LABEL: f14:
+; CHECK: ipm [[REG:%r[0-5]]]
+; CHECK-NEXT: afi [[REG]], 1879048192
+; CHECK-NEXT: sllg [[REG]], [[REG]], 32
+; CHECK-NEXT: srag %r2, [[REG]], 63
+; CHECK: br %r14
+  %cond = fcmp une float %a, %b
+  %res = select i1 %cond, i64 -1, i64 0
+  ret i64 %res
+}
openSUSE Build Service is sponsored by