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