Subzero: Use setcc for most fcmp conditions, instead of control flow.

For C/C++ semantics, this applies to all the FP comparisons except == and != which require two comparisons due to ordered/unordered requirements.  For == and !=, two comparisons and control flow are still used.

BUG= https://code.google.com/p/nativeclient/issues/detail?id=4095
TEST= crosstest/test_fcmp
R=jvoung@chromium.org

Review URL: https://codereview.chromium.org/1148023003
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index 478a6b6..0896c47 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -2702,14 +2702,15 @@
   //   FakeUse(a)         /* only if C1 != Br_None */
   //   mov a, !<default>  /* only if C1 != Br_None */
   //   label:             /* only if C1 != Br_None */
+  //
+  // setcc lowering when C1 != Br_None && C2 == Br_None:
+  //   ucomiss b, c       /* but swap b,c order if SwapOperands==true */
+  //   setcc a, C1
   InstFcmp::FCond Condition = Inst->getCondition();
   size_t Index = static_cast<size_t>(Condition);
   assert(Index < TableFcmpSize);
-  if (TableFcmp[Index].SwapScalarOperands) {
-    Operand *Tmp = Src0;
-    Src0 = Src1;
-    Src1 = Tmp;
-  }
+  if (TableFcmp[Index].SwapScalarOperands)
+    std::swap(Src0, Src1);
   bool HasC1 = (TableFcmp[Index].C1 != CondX86::Br_None);
   bool HasC2 = (TableFcmp[Index].C2 != CondX86::Br_None);
   if (HasC1) {
@@ -2718,6 +2719,11 @@
     Variable *T = nullptr;
     _mov(T, Src0);
     _ucomiss(T, Src1RM);
+    if (!HasC2) {
+      assert(TableFcmp[Index].Default);
+      _setcc(Dest, TableFcmp[Index].C1);
+      return;
+    }
   }
   Constant *Default = Ctx->getConstantInt32(TableFcmp[Index].Default);
   _mov(Dest, Default);
diff --git a/tests_lit/llvm2ice_tests/fp.pnacl.ll b/tests_lit/llvm2ice_tests/fp.pnacl.ll
index b8568a6..ddd51af 100644
--- a/tests_lit/llvm2ice_tests/fp.pnacl.ll
+++ b/tests_lit/llvm2ice_tests/fp.pnacl.ll
@@ -690,10 +690,10 @@
 }
 ; CHECK-LABEL: fcmpGt
 ; CHECK: ucomiss
-; CHECK: ja
+; CHECK: seta
 ; CHECK: call {{.*}} R_{{.*}} func
 ; CHECK: ucomisd
-; CHECK: ja
+; CHECK: seta
 ; CHECK: call {{.*}} R_{{.*}} func
 
 define internal void @fcmpGe(float %a, float %b, double %c, double %d) {
@@ -718,10 +718,10 @@
 }
 ; CHECK-LABEL: fcmpGe
 ; CHECK: ucomiss
-; CHECK: jb
+; CHECK: setb
 ; CHECK: call {{.*}} R_{{.*}} func
 ; CHECK: ucomisd
-; CHECK: jb
+; CHECK: setb
 ; CHECK: call {{.*}} R_{{.*}} func
 
 define internal void @fcmpLt(float %a, float %b, double %c, double %d) {
@@ -746,10 +746,10 @@
 }
 ; CHECK-LABEL: fcmpLt
 ; CHECK: ucomiss
-; CHECK: ja
+; CHECK: seta
 ; CHECK: call {{.*}} R_{{.*}} func
 ; CHECK: ucomisd
-; CHECK: ja
+; CHECK: seta
 ; CHECK: call {{.*}} R_{{.*}} func
 
 define internal void @fcmpLe(float %a, float %b, double %c, double %d) {
@@ -774,10 +774,10 @@
 }
 ; CHECK-LABEL: fcmpLe
 ; CHECK: ucomiss
-; CHECK: jb
+; CHECK: setb
 ; CHECK: call {{.*}} R_{{.*}} func
 ; CHECK: ucomisd
-; CHECK: jb
+; CHECK: setb
 ; CHECK: call {{.*}} R_{{.*}} func
 
 define internal i32 @fcmpFalseFloat(float %a, float %b) {
@@ -828,7 +828,7 @@
 }
 ; CHECK-LABEL: fcmpOgtFloat
 ; CHECK: ucomiss
-; CHECK: ja
+; CHECK: seta
 
 define internal i32 @fcmpOgtDouble(double %a, double %b) {
 entry:
@@ -838,7 +838,7 @@
 }
 ; CHECK-LABEL: fcmpOgtDouble
 ; CHECK: ucomisd
-; CHECK: ja
+; CHECK: seta
 
 define internal i32 @fcmpOgeFloat(float %a, float %b) {
 entry:
@@ -848,7 +848,7 @@
 }
 ; CHECK-LABEL: fcmpOgeFloat
 ; CHECK: ucomiss
-; CHECK: jae
+; CHECK: setae
 
 define internal i32 @fcmpOgeDouble(double %a, double %b) {
 entry:
@@ -858,7 +858,7 @@
 }
 ; CHECK-LABEL: fcmpOgeDouble
 ; CHECK: ucomisd
-; CHECK: jae
+; CHECK: setae
 
 define internal i32 @fcmpOltFloat(float %a, float %b) {
 entry:
@@ -868,7 +868,7 @@
 }
 ; CHECK-LABEL: fcmpOltFloat
 ; CHECK: ucomiss
-; CHECK: ja
+; CHECK: seta
 
 define internal i32 @fcmpOltDouble(double %a, double %b) {
 entry:
@@ -878,7 +878,7 @@
 }
 ; CHECK-LABEL: fcmpOltDouble
 ; CHECK: ucomisd
-; CHECK: ja
+; CHECK: seta
 
 define internal i32 @fcmpOleFloat(float %a, float %b) {
 entry:
@@ -888,7 +888,7 @@
 }
 ; CHECK-LABEL: fcmpOleFloat
 ; CHECK: ucomiss
-; CHECK: jae
+; CHECK: setae
 
 define internal i32 @fcmpOleDouble(double %a, double %b) {
 entry:
@@ -898,7 +898,7 @@
 }
 ; CHECK-LABEL: fcmpOleDouble
 ; CHECK: ucomisd
-; CHECK: jae
+; CHECK: setae
 
 define internal i32 @fcmpOneFloat(float %a, float %b) {
 entry:
@@ -908,7 +908,7 @@
 }
 ; CHECK-LABEL: fcmpOneFloat
 ; CHECK: ucomiss
-; CHECK: jne
+; CHECK: setne
 
 define internal i32 @fcmpOneDouble(double %a, double %b) {
 entry:
@@ -918,7 +918,7 @@
 }
 ; CHECK-LABEL: fcmpOneDouble
 ; CHECK: ucomisd
-; CHECK: jne
+; CHECK: setne
 
 define internal i32 @fcmpOrdFloat(float %a, float %b) {
 entry:
@@ -928,7 +928,7 @@
 }
 ; CHECK-LABEL: fcmpOrdFloat
 ; CHECK: ucomiss
-; CHECK: jnp
+; CHECK: setnp
 
 define internal i32 @fcmpOrdDouble(double %a, double %b) {
 entry:
@@ -938,7 +938,7 @@
 }
 ; CHECK-LABEL: fcmpOrdDouble
 ; CHECK: ucomisd
-; CHECK: jnp
+; CHECK: setnp
 
 define internal i32 @fcmpUeqFloat(float %a, float %b) {
 entry:
@@ -948,7 +948,7 @@
 }
 ; CHECK-LABEL: fcmpUeqFloat
 ; CHECK: ucomiss
-; CHECK: je
+; CHECK: sete
 
 define internal i32 @fcmpUeqDouble(double %a, double %b) {
 entry:
@@ -958,7 +958,7 @@
 }
 ; CHECK-LABEL: fcmpUeqDouble
 ; CHECK: ucomisd
-; CHECK: je
+; CHECK: sete
 
 define internal i32 @fcmpUgtFloat(float %a, float %b) {
 entry:
@@ -968,7 +968,7 @@
 }
 ; CHECK-LABEL: fcmpUgtFloat
 ; CHECK: ucomiss
-; CHECK: jb
+; CHECK: setb
 
 define internal i32 @fcmpUgtDouble(double %a, double %b) {
 entry:
@@ -978,7 +978,7 @@
 }
 ; CHECK-LABEL: fcmpUgtDouble
 ; CHECK: ucomisd
-; CHECK: jb
+; CHECK: setb
 
 define internal i32 @fcmpUgeFloat(float %a, float %b) {
 entry:
@@ -988,7 +988,7 @@
 }
 ; CHECK-LABEL: fcmpUgeFloat
 ; CHECK: ucomiss
-; CHECK: jbe
+; CHECK: setbe
 
 define internal i32 @fcmpUgeDouble(double %a, double %b) {
 entry:
@@ -998,7 +998,7 @@
 }
 ; CHECK-LABEL: fcmpUgeDouble
 ; CHECK: ucomisd
-; CHECK: jbe
+; CHECK: setbe
 
 define internal i32 @fcmpUltFloat(float %a, float %b) {
 entry:
@@ -1008,7 +1008,7 @@
 }
 ; CHECK-LABEL: fcmpUltFloat
 ; CHECK: ucomiss
-; CHECK: jb
+; CHECK: setb
 
 define internal i32 @fcmpUltDouble(double %a, double %b) {
 entry:
@@ -1018,7 +1018,7 @@
 }
 ; CHECK-LABEL: fcmpUltDouble
 ; CHECK: ucomisd
-; CHECK: jb
+; CHECK: setb
 
 define internal i32 @fcmpUleFloat(float %a, float %b) {
 entry:
@@ -1028,7 +1028,7 @@
 }
 ; CHECK-LABEL: fcmpUleFloat
 ; CHECK: ucomiss
-; CHECK: jbe
+; CHECK: setbe
 
 define internal i32 @fcmpUleDouble(double %a, double %b) {
 entry:
@@ -1038,7 +1038,7 @@
 }
 ; CHECK-LABEL: fcmpUleDouble
 ; CHECK: ucomisd
-; CHECK: jbe
+; CHECK: setbe
 
 define internal i32 @fcmpUneFloat(float %a, float %b) {
 entry:
@@ -1070,7 +1070,7 @@
 }
 ; CHECK-LABEL: fcmpUnoFloat
 ; CHECK: ucomiss
-; CHECK: jp
+; CHECK: setp
 
 define internal i32 @fcmpUnoDouble(double %a, double %b) {
 entry:
@@ -1080,7 +1080,7 @@
 }
 ; CHECK-LABEL: fcmpUnoDouble
 ; CHECK: ucomisd
-; CHECK: jp
+; CHECK: setp
 
 define internal i32 @fcmpTrueFloat(float %a, float %b) {
 entry:
@@ -1168,7 +1168,7 @@
 }
 ; CHECK-LABEL: selectFloatVarVar
 ; CHECK: ucomiss
-; CHECK: ja
+; CHECK: seta
 ; CHECK: fld
 
 define internal double @selectDoubleVarVar(double %a, double %b) {
@@ -1179,5 +1179,5 @@
 }
 ; CHECK-LABEL: selectDoubleVarVar
 ; CHECK: ucomisd
-; CHECK: ja
+; CHECK: seta
 ; CHECK: fld