Subzero: Legalize FP constants directly into memory operands.
Previously, the legalize() function would always force a floating point constant into an xmm register before it could be used in an instruction. This uses an extra register unnecessarily when the instruction allows a memory operand for that operand.
We improve this by lowering the FP constant operand to an OperandX8632Mem that wraps a ConstantRelocatable representing the label for the constant pool entry, e.g. [.L$float$0]. (This may end up being copied into an xmm register if the instruction doesn't allow a memory operand for that operand.)
BUG= https://code.google.com/p/nativeclient/issues/detail?id=4095
R=jvoung@chromium.org
Review URL: https://codereview.chromium.org/1163943005
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index 45d6892..b8b633a 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -4590,6 +4590,7 @@
Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed,
int32_t RegNum) {
+ Type Ty = From->getType();
// Assert that a physical register is allowed. To date, all calls
// to legalize() allow a physical register. If a physical register
// needs to be explicitly disallowed, then new code will need to be
@@ -4614,9 +4615,9 @@
RegIndex = legalizeToVar(Index);
}
if (Base != RegBase || Index != RegIndex) {
- From = OperandX8632Mem::create(
- Func, Mem->getType(), RegBase, Mem->getOffset(), RegIndex,
- Mem->getShift(), Mem->getSegmentRegister());
+ From =
+ OperandX8632Mem::create(Func, Ty, RegBase, Mem->getOffset(), RegIndex,
+ Mem->getShift(), Mem->getSegmentRegister());
}
if (!(Allowed & Legal_Mem)) {
@@ -4637,17 +4638,27 @@
// overestimated. If the constant being lowered is a 64 bit value,
// then the result should be split and the lo and hi components will
// need to go in uninitialized registers.
- if (isVectorType(From->getType()))
- return makeVectorOfZeros(From->getType(), RegNum);
- From = Ctx->getConstantZero(From->getType());
+ if (isVectorType(Ty))
+ return makeVectorOfZeros(Ty, RegNum);
+ From = Ctx->getConstantZero(Ty);
}
// There should be no constants of vector type (other than undef).
- assert(!isVectorType(From->getType()));
+ assert(!isVectorType(Ty));
+ // Convert a scalar floating point constant into an explicit
+ // memory operand.
+ if (isScalarFloatingType(Ty)) {
+ Variable *Base = nullptr;
+ std::string Buffer;
+ llvm::raw_string_ostream StrBuf(Buffer);
+ llvm::cast<Constant>(From)->emitPoolLabel(StrBuf);
+ Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true);
+ From = OperandX8632Mem::create(Func, Ty, Base, Offset);
+ }
bool NeedsReg = false;
- if (!(Allowed & Legal_Imm))
+ if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty))
// Immediate specifically not allowed
NeedsReg = true;
- if (!(Allowed & Legal_Mem) && isScalarFloatingType(From->getType()))
+ if (!(Allowed & Legal_Mem) && isScalarFloatingType(Ty))
// On x86, FP constants are lowered to mem operands.
NeedsReg = true;
if (NeedsReg) {
diff --git a/tests_lit/llvm2ice_tests/bitcast.ll b/tests_lit/llvm2ice_tests/bitcast.ll
index 3e7c778..40a654c 100644
--- a/tests_lit/llvm2ice_tests/bitcast.ll
+++ b/tests_lit/llvm2ice_tests/bitcast.ll
@@ -10,7 +10,6 @@
}
; CHECK-LABEL: cast_f2i
; CHECK: mov eax
-; CHECK: ret
define internal float @cast_i2f(i32 %i) {
entry:
@@ -19,7 +18,6 @@
}
; CHECK-LABEL: cast_i2f
; CHECK: fld DWORD PTR
-; CHECK: ret
define internal i64 @cast_d2ll(double %d) {
entry:
@@ -28,7 +26,6 @@
}
; CHECK-LABEL: cast_d2ll
; CHECK: mov edx
-; CHECK: ret
define internal i64 @cast_d2ll_const() {
entry:
@@ -36,9 +33,8 @@
ret i64 %v0
}
; CHECK-LABEL: cast_d2ll_const
-; CHECK: movsd xmm{{.*}},QWORD PTR
-; CHECK: mov edx
-; CHECK: ret
+; CHECK: mov e{{..}},DWORD PTR ds:0x0 {{.*}} .L$double$0
+; CHECK: mov e{{..}},DWORD PTR ds:0x4 {{.*}} .L$double$0
define internal double @cast_ll2d(i64 %ll) {
entry:
@@ -47,7 +43,6 @@
}
; CHECK-LABEL: cast_ll2d
; CHECK: fld QWORD PTR
-; CHECK: ret
define internal double @cast_ll2d_const() {
entry:
@@ -58,4 +53,3 @@
; CHECK: mov {{.*}},0x73ce2ff2
; CHECK: mov {{.*}},0xb3a
; CHECK: fld QWORD PTR
-; CHECK: ret
diff --git a/tests_lit/llvm2ice_tests/undef.ll b/tests_lit/llvm2ice_tests/undef.ll
index 1f2dd6b..9d9014a 100644
--- a/tests_lit/llvm2ice_tests/undef.ll
+++ b/tests_lit/llvm2ice_tests/undef.ll
@@ -182,7 +182,7 @@
%val = insertelement <4 x float> %arg, float undef, i32 0
ret <4 x float> %val
; CHECK-LABEL: vector_insertelement_arg2
-; CHECK: movss {{.*}},DWORD PTR {{.*}} .L$float$0
+; CHECK: {{movss|insertps}} {{.*}},DWORD PTR {{.*}} .L$float$0
}
define float @vector_extractelement_v4f32_index_0() {