Commit 98cc08ca by John Porto

Subzero. ARM32. Strength reduce multiplications.

parent 614140e2
...@@ -49,3 +49,37 @@ SINTOP_TABLE ...@@ -49,3 +49,37 @@ SINTOP_TABLE
v4f32 test##inst(v4f32 a, v4f32 b) { return func(a op b); } v4f32 test##inst(v4f32 a, v4f32 b) { return func(a op b); }
FPOP_TABLE FPOP_TABLE
#undef X #undef X
#define X(mult_by) \
bool testMultiplyBy##mult_by(bool a, bool /*unused*/) { \
return a * (mult_by); \
} \
bool testMultiplyByNeg##mult_by(bool a, bool /*unused*/) { \
return a * (-(mult_by)); \
} \
uint8_t testMultiplyBy##mult_by(uint8_t a, uint8_t /*unused*/) { \
return a * (mult_by); \
} \
uint8_t testMultiplyByNeg##mult_by(uint8_t a, uint8_t /*unused*/) { \
return a * (-(mult_by)); \
} \
uint16_t testMultiplyBy##mult_by(uint16_t a, uint16_t /*unused*/) { \
return a * (mult_by); \
} \
uint16_t testMultiplyByNeg##mult_by(uint16_t a, uint16_t /*unused*/) { \
return a * (-(mult_by)); \
} \
uint32_t testMultiplyBy##mult_by(uint32_t a, uint32_t /*unused*/) { \
return a * (mult_by); \
} \
uint32_t testMultiplyByNeg##mult_by(uint32_t a, uint32_t /*unused*/) { \
return a * (-(mult_by)); \
} \
uint64_t testMultiplyBy##mult_by(uint64_t a, uint64_t /*unused*/) { \
return a * (mult_by); \
} \
uint64_t testMultiplyByNeg##mult_by(uint64_t a, uint64_t /*unused*/) { \
return a * (-(mult_by)); \
}
MULIMM_TABLE
#undef X
...@@ -81,4 +81,25 @@ ...@@ -81,4 +81,25 @@
10.0, FLT_MIN, FLT_MAX, \ 10.0, FLT_MIN, FLT_MAX, \
DBL_MIN, DBL_MAX } DBL_MIN, DBL_MAX }
#define MULIMM_TABLE \
/* mult_by */ \
X( 0) \
X( 1) \
X( 2) \
X( 3) \
X( 4) \
X( 5) \
X( 7) \
X( 8) \
X( 9) \
X( 10) \
X( 25) \
X( 100) \
X( 232) \
X(0x00FFF001) \
X(0x01000000) \
X(0x7FFFF07F) \
X(0x80000000) \
//#define X(mult_by)
#endif // TEST_ARITH_DEF #endif // TEST_ARITH_DEF
...@@ -60,3 +60,17 @@ double mySqrt(double a); ...@@ -60,3 +60,17 @@ double mySqrt(double a);
float myFabs(float a); float myFabs(float a);
double myFabs(double a); double myFabs(double a);
v4f32 myFabs(v4f32 a); v4f32 myFabs(v4f32 a);
#define X(mult_by) \
bool testMultiplyBy##mult_by(bool a, bool); \
bool testMultiplyByNeg##mult_by(bool a, bool); \
uint8_t testMultiplyBy##mult_by(uint8_t a, uint8_t); \
uint8_t testMultiplyByNeg##mult_by(uint8_t a, uint8_t); \
uint16_t testMultiplyBy##mult_by(uint16_t a, uint16_t); \
uint16_t testMultiplyByNeg##mult_by(uint16_t a, uint16_t); \
uint32_t testMultiplyBy##mult_by(uint32_t a, uint32_t); \
uint32_t testMultiplyByNeg##mult_by(uint32_t a, uint32_t); \
uint64_t testMultiplyBy##mult_by(uint64_t a, uint64_t); \
uint64_t testMultiplyByNeg##mult_by(uint64_t a, uint64_t);
MULIMM_TABLE
#undef X
...@@ -73,7 +73,15 @@ void testsInt(size_t &TotalTests, size_t &Passes, size_t &Failures) { ...@@ -73,7 +73,15 @@ void testsInt(size_t &TotalTests, size_t &Passes, size_t &Failures) {
, ,
SINTOP_TABLE SINTOP_TABLE
#undef X #undef X
}; #define X(mult_by) \
{ \
"Mult-By-" STR(mult_by), testMultiplyBy##mult_by, \
Subzero_::testMultiplyBy##mult_by, NULL, NULL, false \
} \
, {"Mult-By-Neg-" STR(mult_by), testMultiplyByNeg##mult_by, \
Subzero_::testMultiplyByNeg##mult_by, NULL, NULL, false},
MULIMM_TABLE};
#undef X
const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs); const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
if (sizeof(TypeUnsigned) <= sizeof(uint32_t)) { if (sizeof(TypeUnsigned) <= sizeof(uint32_t)) {
......
...@@ -977,15 +977,16 @@ private: ...@@ -977,15 +977,16 @@ private:
// AllowTemporaryWithNoReg indicates if TargetARM32::makeReg() can be invoked // AllowTemporaryWithNoReg indicates if TargetARM32::makeReg() can be invoked
// without specifying a physical register. This is needed for creating unbound // without specifying a physical register. This is needed for creating unbound
// temporaries during Ice -> ARM lowering, but before register allocation. // temporaries during Ice -> ARM lowering, but before register allocation.
// This a safe-guard that, during the legalization post-passes no unbound // This a safe-guard that no unbound temporaries are created during the
// temporaries are created. // legalization post-passes.
bool AllowTemporaryWithNoReg = true; bool AllowTemporaryWithNoReg = true;
// ForbidTemporaryWithoutReg is a RAII class that manages // ForbidTemporaryWithoutReg is a RAII class that manages
// AllowTemporaryWithNoReg. // AllowTemporaryWithNoReg.
class ForbidTemporaryWithoutReg { class ForbidTemporaryWithoutReg {
ForbidTemporaryWithoutReg() = delete; ForbidTemporaryWithoutReg() = delete;
ForbidTemporaryWithoutReg(const ForbidTemporaryWithoutReg&) = delete; ForbidTemporaryWithoutReg(const ForbidTemporaryWithoutReg &) = delete;
ForbidTemporaryWithoutReg &operator=(const ForbidTemporaryWithoutReg&) = delete; ForbidTemporaryWithoutReg &
operator=(const ForbidTemporaryWithoutReg &) = delete;
public: public:
explicit ForbidTemporaryWithoutReg(TargetARM32 *Target) : Target(Target) { explicit ForbidTemporaryWithoutReg(TargetARM32 *Target) : Target(Target) {
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \ ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \
; RUN: -i %s --args -O2 --skip-unimplemented \ ; RUN: -i %s --args -O2 --skip-unimplemented \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 %s ; RUN: --command FileCheck --check-prefix ARM32 --check-prefix ARM-OPT2 %s
; RUN: %if --need=target_ARM32 --need=allow_dump \ ; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \ ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \
; RUN: -i %s --args -O2 --mattr=hwdiv-arm --skip-unimplemented \ ; RUN: -i %s --args -O2 --mattr=hwdiv-arm --skip-unimplemented \
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \ ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \
; RUN: -i %s --args -Om1 --skip-unimplemented \ ; RUN: -i %s --args -Om1 --skip-unimplemented \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 %s ; RUN: --command FileCheck --check-prefix ARM32 --check-prefix ARM32-OPTM1 %s
; ;
; RUN: %if --need=target_MIPS32 --need=allow_dump \ ; RUN: %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble --disassemble --target mips32\ ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target mips32\
...@@ -117,8 +117,11 @@ entry: ...@@ -117,8 +117,11 @@ entry:
; CHECK-LABEL: MulImm ; CHECK-LABEL: MulImm
; CHECK: imul e{{.*}},e{{.*}},0x63 ; CHECK: imul e{{.*}},e{{.*}},0x63
; ARM32-LABEL: MulImm ; ARM32-LABEL: MulImm
; ARM32: movw {{.*}}, #99 ; ARM32-OPTM1: movw {{.*}}, #99
; ARM32: mul r{{.*}}, r{{.*}}, r{{.*}} ; ARM32-OPTM1: mul r{{.*}}, r{{.*}}, r{{.*}}
; ARM32-OPT2: rsb [[T:r[0-9]+]], [[S:r[0-9]+]], [[S]], lsl #2
; ARM32-OPT2-DAG: add [[T]], [[T]], [[S]], lsl #7
; ARM32-OPT2-DAG: sub [[T]], [[T]], [[S]], lsl #5
; MIPS32-LABEL: MulImm ; MIPS32-LABEL: MulImm
; MIPS32: mul ; MIPS32: mul
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment