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() {