Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
swiftshader
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
swiftshader
Commits
4a5e6d05
Commit
4a5e6d05
authored
Nov 04, 2015
by
John Porto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Subzero. ARM32. Implements bool folding.
BUG=
https://code.google.com/p/nativeclient/issues/detail?id=4076
R=stichnot@chromium.org Review URL:
https://codereview.chromium.org/1414883007
.
parent
57586f73
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
807 additions
and
357 deletions
+807
-357
IceTargetLoweringARM32.cpp
src/IceTargetLoweringARM32.cpp
+377
-85
IceTargetLoweringARM32.h
src/IceTargetLoweringARM32.h
+125
-2
branch-mult-fwd.ll
tests_lit/assembler/arm32/branch-mult-fwd.ll
+16
-16
64bit.pnacl.ll
tests_lit/llvm2ice_tests/64bit.pnacl.ll
+96
-59
bool-folding.ll
tests_lit/llvm2ice_tests/bool-folding.ll
+61
-75
branch-opt.ll
tests_lit/llvm2ice_tests/branch-opt.ll
+6
-11
fp.cmp.ll
tests_lit/llvm2ice_tests/fp.cmp.ll
+75
-64
select-opt.ll
tests_lit/llvm2ice_tests/select-opt.ll
+12
-8
test_i1.ll
tests_lit/llvm2ice_tests/test_i1.ll
+39
-37
No files found.
src/IceTargetLoweringARM32.cpp
View file @
4a5e6d05
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
#include "IceGlobalInits.h"
#include "IceGlobalInits.h"
#include "IceInstARM32.def"
#include "IceInstARM32.def"
#include "IceInstARM32.h"
#include "IceInstARM32.h"
#include "IceInstVarIter.h"
#include "IceLiveness.h"
#include "IceLiveness.h"
#include "IceOperand.h"
#include "IceOperand.h"
#include "IcePhiLoweringImpl.h"
#include "IcePhiLoweringImpl.h"
...
@@ -1803,22 +1804,46 @@ void TargetARM32::lowerAssign(const InstAssign *Inst) {
...
@@ -1803,22 +1804,46 @@ void TargetARM32::lowerAssign(const InstAssign *Inst) {
}
}
}
}
void
TargetARM32
::
lowerBr
(
const
InstBr
*
Inst
)
{
void
TargetARM32
::
lowerBr
(
const
InstBr
*
Inst
r
)
{
if
(
Inst
->
isUnconditional
())
{
if
(
Inst
r
->
isUnconditional
())
{
_br
(
Inst
->
getTargetUnconditional
());
_br
(
Inst
r
->
getTargetUnconditional
());
return
;
return
;
}
}
Operand
*
Cond
=
Inst
->
getCondition
();
Operand
*
Cond
=
Instr
->
getCondition
();
// TODO(jvoung): Handle folding opportunities.
CondARM32
::
Cond
BrCondTrue0
=
CondARM32
::
NE
;
CondARM32
::
Cond
BrCondTrue1
=
CondARM32
::
kNone
;
CondARM32
::
Cond
BrCondFalse
=
CondARM32
::
kNone
;
if
(
!
_mov_i1_to_flags
(
Cond
,
&
BrCondTrue0
,
&
BrCondTrue1
,
&
BrCondFalse
))
{
// "Cond" was not fold.
Type
Ty
=
Cond
->
getType
();
Type
Ty
=
Cond
->
getType
();
Variable
*
Src0R
=
legalizeToReg
(
Cond
);
Variable
*
Src0R
=
legalizeToReg
(
Cond
);
assert
(
Ty
==
IceType_i1
);
assert
(
Ty
==
IceType_i1
);
if
(
Ty
!=
IceType_i32
)
if
(
Ty
!=
IceType_i32
)
_uxt
(
Src0R
,
Src0R
);
_uxt
(
Src0R
,
Src0R
);
Constant
*
Zero
=
Ctx
->
getConstantZero
(
IceType_i32
);
Constant
*
_0
=
Ctx
->
getConstantZero
(
IceType_i32
);
_cmp
(
Src0R
,
Zero
);
_cmp
(
Src0R
,
_0
);
_br
(
Inst
->
getTargetTrue
(),
Inst
->
getTargetFalse
(),
CondARM32
::
NE
);
BrCondTrue0
=
CondARM32
::
NE
;
}
if
(
BrCondTrue1
!=
CondARM32
::
kNone
)
{
_br
(
Instr
->
getTargetTrue
(),
BrCondTrue1
);
}
if
(
BrCondTrue0
==
CondARM32
::
kNone
)
{
assert
(
BrCondTrue1
==
CondARM32
::
kNone
);
_br
(
Instr
->
getTargetFalse
());
return
;
}
if
(
BrCondTrue0
==
CondARM32
::
AL
)
{
assert
(
BrCondTrue1
==
CondARM32
::
kNone
);
assert
(
BrCondFalse
==
CondARM32
::
kNone
);
_br
(
Instr
->
getTargetTrue
());
return
;
}
_br
(
Instr
->
getTargetTrue
(),
Instr
->
getTargetFalse
(),
BrCondTrue0
);
}
}
void
TargetARM32
::
lowerCall
(
const
InstCall
*
Instr
)
{
void
TargetARM32
::
lowerCall
(
const
InstCall
*
Instr
)
{
...
@@ -2050,13 +2075,22 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
...
@@ -2050,13 +2075,22 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
if
(
Src0
->
getType
()
==
IceType_i32
)
{
if
(
Src0
->
getType
()
==
IceType_i32
)
{
Operand
*
Src0RF
=
legalize
(
Src0
,
Legal_Reg
|
Legal_Flex
);
Operand
*
Src0RF
=
legalize
(
Src0
,
Legal_Reg
|
Legal_Flex
);
_mov
(
T_Lo
,
Src0RF
);
_mov
(
T_Lo
,
Src0RF
);
}
else
if
(
Src0
->
getType
()
=
=
IceType_i1
)
{
}
else
if
(
Src0
->
getType
()
!
=
IceType_i1
)
{
Variable
*
Src0R
=
legalizeToReg
(
Src0
);
Variable
*
Src0R
=
legalizeToReg
(
Src0
);
_lsl
(
T_Lo
,
Src0R
,
ShiftAmt
);
_sxt
(
T_Lo
,
Src0R
);
_asr
(
T_Lo
,
T_Lo
,
ShiftAmt
);
}
else
{
CondARM32
::
Cond
CondTrue0
,
CondTrue1
,
CondFalse
;
if
(
_mov_i1_to_flags
(
Src0
,
&
CondTrue0
,
&
CondTrue1
,
&
CondFalse
))
{
// Handle bool folding.
Constant
*
_0
=
Ctx
->
getConstantZero
(
IceType_i32
);
Operand
*
_m1
=
legalize
(
Ctx
->
getConstantInt32
(
-
1
),
Legal_Reg
|
Legal_Flex
);
_cmov
(
T_Lo
,
_m1
,
CondTrue0
,
CondTrue1
,
_0
,
CondFalse
);
}
else
{
}
else
{
Variable
*
Src0R
=
legalizeToReg
(
Src0
);
Variable
*
Src0R
=
legalizeToReg
(
Src0
);
_sxt
(
T_Lo
,
Src0R
);
_lsl
(
T_Lo
,
Src0R
,
ShiftAmt
);
_asr
(
T_Lo
,
T_Lo
,
ShiftAmt
);
}
}
}
_mov
(
DestLo
,
T_Lo
);
_mov
(
DestLo
,
T_Lo
);
Variable
*
T_Hi
=
makeReg
(
DestHi
->
getType
());
Variable
*
T_Hi
=
makeReg
(
DestHi
->
getType
());
...
@@ -2068,22 +2102,31 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
...
@@ -2068,22 +2102,31 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
_mov
(
T_Hi
,
T_Lo
);
_mov
(
T_Hi
,
T_Lo
);
}
}
_mov
(
DestHi
,
T_Hi
);
_mov
(
DestHi
,
T_Hi
);
}
else
if
(
Src0
->
getType
()
==
IceType_i1
)
{
}
else
if
(
Src0
->
getType
()
!=
IceType_i1
)
{
// t1 = sxt src; dst = t1
Variable
*
Src0R
=
legalizeToReg
(
Src0
);
Variable
*
T
=
makeReg
(
Dest
->
getType
());
_sxt
(
T
,
Src0R
);
_mov
(
Dest
,
T
);
}
else
{
Variable
*
T
=
makeReg
(
Dest
->
getType
());
CondARM32
::
Cond
CondTrue0
,
CondTrue1
,
CondFalse
;
if
(
_mov_i1_to_flags
(
Src0
,
&
CondTrue0
,
&
CondTrue1
,
&
CondFalse
))
{
// Handle bool folding.
Constant
*
_0
=
Ctx
->
getConstantZero
(
IceType_i32
);
Operand
*
_m1
=
legalize
(
Ctx
->
getConstantInt32
(
-
1
),
Legal_Reg
|
Legal_Flex
);
_cmov
(
T
,
_m1
,
CondTrue0
,
CondTrue1
,
_0
,
CondFalse
);
}
else
{
// GPR registers are 32-bit, so just use 31 as dst_bitwidth - 1.
// GPR registers are 32-bit, so just use 31 as dst_bitwidth - 1.
// lsl t1, src_reg, 31
// lsl t1, src_reg, 31
// asr t1, t1, 31
// asr t1, t1, 31
// dst = t1
// dst = t1
Variable
*
Src0R
=
legalizeToReg
(
Src0
);
Variable
*
Src0R
=
legalizeToReg
(
Src0
);
Constant
*
ShiftAmt
=
Ctx
->
getConstantInt32
(
31
);
Constant
*
ShiftAmt
=
Ctx
->
getConstantInt32
(
31
);
Variable
*
T
=
makeReg
(
Dest
->
getType
());
_lsl
(
T
,
Src0R
,
ShiftAmt
);
_lsl
(
T
,
Src0R
,
ShiftAmt
);
_asr
(
T
,
T
,
ShiftAmt
);
_asr
(
T
,
T
,
ShiftAmt
);
_mov
(
Dest
,
T
);
}
}
else
{
// t1 = sxt src; dst = t1
Variable
*
Src0R
=
legalizeToReg
(
Src0
);
Variable
*
T
=
makeReg
(
Dest
->
getType
());
_sxt
(
T
,
Src0R
);
_mov
(
Dest
,
T
);
_mov
(
Dest
,
T
);
}
}
break
;
break
;
...
@@ -2096,10 +2139,23 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
...
@@ -2096,10 +2139,23 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
}
else
if
(
Dest
->
getType
()
==
IceType_i64
)
{
}
else
if
(
Dest
->
getType
()
==
IceType_i64
)
{
// t1=uxtb src; dst.lo=t1; dst.hi=0
// t1=uxtb src; dst.lo=t1; dst.hi=0
Constant
*
Zero
=
Ctx
->
getConstantZero
(
IceType_i32
);
Constant
*
_0
=
Ctx
->
getConstantZero
(
IceType_i32
);
Constant
*
_1
=
Ctx
->
getConstantInt32
(
1
);
Variable
*
DestLo
=
llvm
::
cast
<
Variable
>
(
loOperand
(
Dest
));
Variable
*
DestLo
=
llvm
::
cast
<
Variable
>
(
loOperand
(
Dest
));
Variable
*
DestHi
=
llvm
::
cast
<
Variable
>
(
hiOperand
(
Dest
));
Variable
*
DestHi
=
llvm
::
cast
<
Variable
>
(
hiOperand
(
Dest
));
Variable
*
T_Lo
=
makeReg
(
DestLo
->
getType
());
Variable
*
T_Lo
=
makeReg
(
DestLo
->
getType
());
CondARM32
::
Cond
CondTrue0
,
CondTrue1
,
CondFalse
;
if
(
_mov_i1_to_flags
(
Src0
,
&
CondTrue0
,
&
CondTrue1
,
&
CondFalse
))
{
// Handle folding opportunities.
Variable
*
T_Hi
=
makeReg
(
DestLo
->
getType
());
_mov
(
T_Hi
,
_0
);
_mov
(
DestHi
,
T_Hi
);
_cmov
(
T_Lo
,
_1
,
CondTrue0
,
CondTrue1
,
_0
,
CondFalse
);
_mov
(
DestLo
,
T_Lo
);
return
;
}
// i32 and i1 can just take up the whole register. i32 doesn't need uxt,
// i32 and i1 can just take up the whole register. i32 doesn't need uxt,
// while i1 will have an and mask later anyway.
// while i1 will have an and mask later anyway.
if
(
Src0
->
getType
()
==
IceType_i32
||
Src0
->
getType
()
==
IceType_i1
)
{
if
(
Src0
->
getType
()
==
IceType_i32
||
Src0
->
getType
()
==
IceType_i1
)
{
...
@@ -2115,18 +2171,28 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
...
@@ -2115,18 +2171,28 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
}
}
_mov
(
DestLo
,
T_Lo
);
_mov
(
DestLo
,
T_Lo
);
Variable
*
T_Hi
=
makeReg
(
DestLo
->
getType
());
Variable
*
T_Hi
=
makeReg
(
DestLo
->
getType
());
_mov
(
T_Hi
,
Zero
);
_mov
(
T_Hi
,
_0
);
_mov
(
DestHi
,
T_Hi
);
_mov
(
DestHi
,
T_Hi
);
}
else
if
(
Src0
->
getType
()
==
IceType_i1
)
{
}
else
if
(
Src0
->
getType
()
==
IceType_i1
)
{
Constant
*
_1
=
Ctx
->
getConstantInt32
(
1
);
Variable
*
T
=
makeReg
(
Dest
->
getType
());
CondARM32
::
Cond
CondTrue0
,
CondTrue1
,
CondFalse
;
if
(
_mov_i1_to_flags
(
Src0
,
&
CondTrue0
,
&
CondTrue1
,
&
CondFalse
))
{
// Handle folding opportunities.
Constant
*
_0
=
Ctx
->
getConstantZero
(
IceType_i32
);
_cmov
(
T
,
_1
,
CondTrue0
,
CondTrue1
,
_0
,
CondFalse
);
_mov
(
Dest
,
T
);
return
;
}
// t = Src0; t &= 1; Dest = t
// t = Src0; t &= 1; Dest = t
Operand
*
Src0RF
=
legalize
(
Src0
,
Legal_Reg
|
Legal_Flex
);
Operand
*
Src0RF
=
legalize
(
Src0
,
Legal_Reg
|
Legal_Flex
);
Constant
*
One
=
Ctx
->
getConstantInt32
(
1
);
Variable
*
T
=
makeReg
(
Dest
->
getType
());
// Just use _mov instead of _uxt since all registers are 32-bit. _uxt
// Just use _mov instead of _uxt since all registers are 32-bit. _uxt
// requires the source to be a register so could have required a _mov
// requires the source to be a register so could have required a _mov
// from legalize anyway.
// from legalize anyway.
_mov
(
T
,
Src0RF
);
_mov
(
T
,
Src0RF
);
_and
(
T
,
T
,
One
);
_and
(
T
,
T
,
_1
);
_mov
(
Dest
,
T
);
_mov
(
Dest
,
T
);
}
else
{
}
else
{
// t1 = uxt src; dst = t1
// t1 = uxt src; dst = t1
...
@@ -2397,8 +2463,37 @@ struct {
...
@@ -2397,8 +2463,37 @@ struct {
};
};
}
// end of anonymous namespace
}
// end of anonymous namespace
void
TargetARM32
::
lowerFcmp
(
const
InstFcmp
*
Inst
)
{
void
TargetARM32
::
lowerFcmpCond
(
const
InstFcmp
*
Instr
,
Variable
*
Dest
=
Inst
->
getDest
();
CondARM32
::
Cond
*
CondIfTrue0
,
CondARM32
::
Cond
*
CondIfTrue1
,
CondARM32
::
Cond
*
CondIfFalse
)
{
InstFcmp
::
FCond
Condition
=
Instr
->
getCondition
();
switch
(
Condition
)
{
case
InstFcmp
:
:
False
:
*
CondIfFalse
=
CondARM32
::
AL
;
*
CondIfTrue0
=
*
CondIfTrue1
=
CondARM32
::
kNone
;
break
;
case
InstFcmp
:
:
True
:
*
CondIfFalse
=
*
CondIfTrue1
=
CondARM32
::
kNone
;
*
CondIfTrue0
=
CondARM32
::
AL
;
break
;
default
:
{
Variable
*
Src0R
=
legalizeToReg
(
Instr
->
getSrc
(
0
));
Variable
*
Src1R
=
legalizeToReg
(
Instr
->
getSrc
(
1
));
_vcmp
(
Src0R
,
Src1R
);
_vmrs
();
assert
(
Condition
<
llvm
::
array_lengthof
(
TableFcmp
));
*
CondIfTrue0
=
TableFcmp
[
Condition
].
CC0
;
*
CondIfTrue1
=
TableFcmp
[
Condition
].
CC1
;
*
CondIfFalse
=
(
*
CondIfTrue1
!=
CondARM32
::
kNone
)
?
CondARM32
::
AL
:
InstARM32
::
getOppositeCondition
(
*
CondIfTrue0
);
}
}
}
void
TargetARM32
::
lowerFcmp
(
const
InstFcmp
*
Instr
)
{
Variable
*
Dest
=
Instr
->
getDest
();
if
(
isVectorType
(
Dest
->
getType
()))
{
if
(
isVectorType
(
Dest
->
getType
()))
{
Variable
*
T
=
makeReg
(
Dest
->
getType
());
Variable
*
T
=
makeReg
(
Dest
->
getType
());
Context
.
insert
(
InstFakeDef
::
create
(
Func
,
T
));
Context
.
insert
(
InstFakeDef
::
create
(
Func
,
T
));
...
@@ -2407,48 +2502,43 @@ void TargetARM32::lowerFcmp(const InstFcmp *Inst) {
...
@@ -2407,48 +2502,43 @@ void TargetARM32::lowerFcmp(const InstFcmp *Inst) {
return
;
return
;
}
}
Variable
*
Src0R
=
legalizeToReg
(
Inst
->
getSrc
(
0
));
Variable
*
Src1R
=
legalizeToReg
(
Inst
->
getSrc
(
1
));
Variable
*
T
=
makeReg
(
IceType_i32
);
Variable
*
T
=
makeReg
(
IceType_i32
);
_vcmp
(
Src0R
,
Src1R
);
Operand
*
_1
=
Ctx
->
getConstantInt32
(
1
);
_mov
(
T
,
Ctx
->
getConstantZero
(
IceType_i32
));
Operand
*
_0
=
Ctx
->
getConstantZero
(
IceType_i32
);
_vmrs
();
Operand
*
One
=
Ctx
->
getConstantInt32
(
1
);
CondARM32
::
Cond
CondIfTrue0
,
CondIfTrue1
,
CondIfFalse
;
InstFcmp
::
FCond
Condition
=
Inst
->
getCondition
();
lowerFcmpCond
(
Instr
,
&
CondIfTrue0
,
&
CondIfTrue1
,
&
CondIfFalse
);
assert
(
Condition
<
llvm
::
array_lengthof
(
TableFcmp
));
CondARM32
::
Cond
CC0
=
TableFcmp
[
Condition
].
CC0
;
bool
RedefineT
=
false
;
CondARM32
::
Cond
CC1
=
TableFcmp
[
Condition
].
CC1
;
if
(
CondIfFalse
!=
CondARM32
::
kNone
)
{
if
(
CC0
!=
CondARM32
::
kNone
)
{
assert
(
!
RedefineT
);
_mov
(
T
,
One
,
CC0
);
_mov
(
T
,
_0
,
CondIfFalse
);
// If this mov is not a maybe mov, but an actual mov (i.e., CC0 == AL), we
RedefineT
=
true
;
// don't want to _set_dest_redefined so that liveness + dead-code
}
// elimination will get rid of the previous assignment (i.e., T = 0) above.
// TODO(stichnot,jpp): We should be able to conditionally create the "T=0"
if
(
CondIfTrue0
!=
CondARM32
::
kNone
)
{
// instruction based on CC0, instead of relying on DCE to remove it.
if
(
RedefineT
)
{
if
(
CC0
!=
CondARM32
::
AL
)
_mov_redefined
(
T
,
_1
,
CondIfTrue0
);
_set_dest_redefined
();
}
else
{
_mov
(
T
,
_1
,
CondIfTrue0
);
}
RedefineT
=
true
;
}
}
if
(
CC1
!=
CondARM32
::
kNone
)
{
assert
(
CC0
!=
CondARM32
::
kNone
);
if
(
CondIfTrue1
!=
CondARM32
::
kNone
)
{
assert
(
CC1
!=
CondARM32
::
AL
);
assert
(
RedefineT
);
_mov_redefined
(
T
,
One
,
CC
1
);
_mov_redefined
(
T
,
_1
,
CondIfTrue
1
);
}
}
_mov
(
Dest
,
T
);
_mov
(
Dest
,
T
);
}
}
void
TargetARM32
::
lowerIcmp
(
const
InstIcmp
*
Inst
)
{
void
TargetARM32
::
lowerIcmpCond
(
const
InstIcmp
*
Inst
,
Variable
*
Dest
=
Inst
->
getDest
();
CondARM32
::
Cond
*
CondIfTrue
,
CondARM32
::
Cond
*
CondIfFalse
)
{
Operand
*
Src0
=
legalizeUndef
(
Inst
->
getSrc
(
0
));
Operand
*
Src0
=
legalizeUndef
(
Inst
->
getSrc
(
0
));
Operand
*
Src1
=
legalizeUndef
(
Inst
->
getSrc
(
1
));
Operand
*
Src1
=
legalizeUndef
(
Inst
->
getSrc
(
1
));
if
(
isVectorType
(
Dest
->
getType
()))
{
Variable
*
T
=
makeReg
(
Dest
->
getType
());
Context
.
insert
(
InstFakeDef
::
create
(
Func
,
T
));
_mov
(
Dest
,
T
);
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
return
;
}
// a=icmp cond, b, c ==>
// a=icmp cond, b, c ==>
// GCC does:
// GCC does:
// cmp b.hi, c.hi or cmp b.lo, c.lo
// cmp b.hi, c.hi or cmp b.lo, c.lo
...
@@ -2478,8 +2568,7 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
...
@@ -2478,8 +2568,7 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
//
//
// So, we are going with the GCC version since it's usually better (except
// So, we are going with the GCC version since it's usually better (except
// perhaps for eq/ne). We could revisit special-casing eq/ne later.
// perhaps for eq/ne). We could revisit special-casing eq/ne later.
Constant
*
Zero
=
Ctx
->
getConstantZero
(
IceType_i32
);
Constant
*
One
=
Ctx
->
getConstantInt32
(
1
);
if
(
Src0
->
getType
()
==
IceType_i64
)
{
if
(
Src0
->
getType
()
==
IceType_i64
)
{
InstIcmp
::
ICond
Conditon
=
Inst
->
getCondition
();
InstIcmp
::
ICond
Conditon
=
Inst
->
getCondition
();
size_t
Index
=
static_cast
<
size_t
>
(
Conditon
);
size_t
Index
=
static_cast
<
size_t
>
(
Conditon
);
...
@@ -2497,7 +2586,6 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
...
@@ -2497,7 +2586,6 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
Src1LoRF
=
legalize
(
loOperand
(
Src1
),
Legal_Reg
|
Legal_Flex
);
Src1LoRF
=
legalize
(
loOperand
(
Src1
),
Legal_Reg
|
Legal_Flex
);
Src1HiRF
=
legalize
(
hiOperand
(
Src1
),
Legal_Reg
|
Legal_Flex
);
Src1HiRF
=
legalize
(
hiOperand
(
Src1
),
Legal_Reg
|
Legal_Flex
);
}
}
Variable
*
T
=
makeReg
(
IceType_i32
);
if
(
TableIcmp64
[
Index
].
IsSigned
)
{
if
(
TableIcmp64
[
Index
].
IsSigned
)
{
Variable
*
ScratchReg
=
makeReg
(
IceType_i32
);
Variable
*
ScratchReg
=
makeReg
(
IceType_i32
);
_cmp
(
Src0Lo
,
Src1LoRF
);
_cmp
(
Src0Lo
,
Src1LoRF
);
...
@@ -2509,9 +2597,8 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
...
@@ -2509,9 +2597,8 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
_cmp
(
Src0Hi
,
Src1HiRF
);
_cmp
(
Src0Hi
,
Src1HiRF
);
_cmp
(
Src0Lo
,
Src1LoRF
,
CondARM32
::
EQ
);
_cmp
(
Src0Lo
,
Src1LoRF
,
CondARM32
::
EQ
);
}
}
_mov
(
T
,
One
,
TableIcmp64
[
Index
].
C1
);
*
CondIfTrue
=
TableIcmp64
[
Index
].
C1
;
_mov_redefined
(
T
,
Zero
,
TableIcmp64
[
Index
].
C2
);
*
CondIfFalse
=
TableIcmp64
[
Index
].
C2
;
_mov
(
Dest
,
T
);
return
;
return
;
}
}
...
@@ -2548,7 +2635,6 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
...
@@ -2548,7 +2635,6 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
assert
(
ShiftAmt
>=
0
);
assert
(
ShiftAmt
>=
0
);
Constant
*
ShiftConst
=
nullptr
;
Constant
*
ShiftConst
=
nullptr
;
Variable
*
Src0R
=
nullptr
;
Variable
*
Src0R
=
nullptr
;
Variable
*
T
=
makeReg
(
IceType_i32
);
if
(
ShiftAmt
)
{
if
(
ShiftAmt
)
{
ShiftConst
=
Ctx
->
getConstantInt32
(
ShiftAmt
);
ShiftConst
=
Ctx
->
getConstantInt32
(
ShiftAmt
);
Src0R
=
makeReg
(
IceType_i32
);
Src0R
=
makeReg
(
IceType_i32
);
...
@@ -2556,7 +2642,6 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
...
@@ -2556,7 +2642,6 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
}
else
{
}
else
{
Src0R
=
legalizeToReg
(
Src0
);
Src0R
=
legalizeToReg
(
Src0
);
}
}
_mov
(
T
,
Zero
);
if
(
ShiftAmt
)
{
if
(
ShiftAmt
)
{
Variable
*
Src1R
=
legalizeToReg
(
Src1
);
Variable
*
Src1R
=
legalizeToReg
(
Src1
);
OperandARM32FlexReg
*
Src1RShifted
=
OperandARM32FlexReg
::
create
(
OperandARM32FlexReg
*
Src1RShifted
=
OperandARM32FlexReg
::
create
(
...
@@ -2566,8 +2651,32 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
...
@@ -2566,8 +2651,32 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
Operand
*
Src1RF
=
legalize
(
Src1
,
Legal_Reg
|
Legal_Flex
);
Operand
*
Src1RF
=
legalize
(
Src1
,
Legal_Reg
|
Legal_Flex
);
_cmp
(
Src0R
,
Src1RF
);
_cmp
(
Src0R
,
Src1RF
);
}
}
_mov_redefined
(
T
,
One
,
getIcmp32Mapping
(
Inst
->
getCondition
()));
*
CondIfTrue
=
getIcmp32Mapping
(
Inst
->
getCondition
());
*
CondIfFalse
=
InstARM32
::
getOppositeCondition
(
*
CondIfTrue
);
}
void
TargetARM32
::
lowerIcmp
(
const
InstIcmp
*
Inst
)
{
Variable
*
Dest
=
Inst
->
getDest
();
if
(
isVectorType
(
Dest
->
getType
()))
{
Variable
*
T
=
makeReg
(
Dest
->
getType
());
Context
.
insert
(
InstFakeDef
::
create
(
Func
,
T
));
_mov
(
Dest
,
T
);
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
return
;
}
Constant
*
_0
=
Ctx
->
getConstantZero
(
IceType_i32
);
Constant
*
_1
=
Ctx
->
getConstantInt32
(
1
);
Variable
*
T
=
makeReg
(
IceType_i32
);
CondARM32
::
Cond
CondIfTrue
,
CondIfFalse
;
lowerIcmpCond
(
Inst
,
&
CondIfTrue
,
&
CondIfFalse
);
_mov
(
T
,
_0
,
CondIfFalse
);
_mov_redefined
(
T
,
_1
,
CondIfTrue
);
_mov
(
Dest
,
T
);
_mov
(
Dest
,
T
);
return
;
return
;
}
}
...
@@ -3329,7 +3438,10 @@ void TargetARM32::lowerSelect(const InstSelect *Inst) {
...
@@ -3329,7 +3438,10 @@ void TargetARM32::lowerSelect(const InstSelect *Inst) {
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
return
;
return
;
}
}
// TODO(jvoung): handle folding opportunities.
CondARM32
::
Cond
CondIfTrue0
,
CondIfTrue1
,
CondIfFalse
;
if
(
!
_mov_i1_to_flags
(
Condition
,
&
CondIfTrue0
,
&
CondIfTrue1
,
&
CondIfFalse
))
{
// "Condition" was not fold.
// cmp cond, #0; mov t, SrcF; mov_cond t, SrcT; mov dest, t
// cmp cond, #0; mov t, SrcF; mov_cond t, SrcT; mov dest, t
Variable
*
CmpOpnd0
=
legalizeToReg
(
Condition
);
Variable
*
CmpOpnd0
=
legalizeToReg
(
Condition
);
Type
CmpOpnd0Ty
=
CmpOpnd0
->
getType
();
Type
CmpOpnd0Ty
=
CmpOpnd0
->
getType
();
...
@@ -3338,47 +3450,107 @@ void TargetARM32::lowerSelect(const InstSelect *Inst) {
...
@@ -3338,47 +3450,107 @@ void TargetARM32::lowerSelect(const InstSelect *Inst) {
if
(
CmpOpnd0Ty
!=
IceType_i32
)
if
(
CmpOpnd0Ty
!=
IceType_i32
)
_uxt
(
CmpOpnd0
,
CmpOpnd0
);
_uxt
(
CmpOpnd0
,
CmpOpnd0
);
_cmp
(
CmpOpnd0
,
CmpOpnd1
);
_cmp
(
CmpOpnd0
,
CmpOpnd1
);
static
constexpr
CondARM32
::
Cond
Cond
=
CondARM32
::
NE
;
CondIfTrue0
=
CondARM32
::
NE
;
CondIfTrue1
=
CondARM32
::
kNone
;
CondIfFalse
=
CondARM32
::
EQ
;
}
if
(
DestTy
==
IceType_i64
)
{
if
(
DestTy
==
IceType_i64
)
{
SrcT
=
legalizeUndef
(
SrcT
);
SrcT
=
legalizeUndef
(
SrcT
);
SrcF
=
legalizeUndef
(
SrcF
);
SrcF
=
legalizeUndef
(
SrcF
);
// Set the low portion.
// Set the low portion.
Variable
*
DestLo
=
llvm
::
cast
<
Variable
>
(
loOperand
(
Dest
));
Variable
*
DestLo
=
llvm
::
cast
<
Variable
>
(
loOperand
(
Dest
));
Operand
*
SrcTLo
=
legalize
(
loOperand
(
SrcT
),
Legal_Reg
|
Legal_Flex
);
Operand
*
SrcFLo
=
legalize
(
loOperand
(
SrcF
),
Legal_Reg
|
Legal_Flex
);
Operand
*
SrcFLo
=
legalize
(
loOperand
(
SrcF
),
Legal_Reg
|
Legal_Flex
);
Variable
*
TLo
=
makeReg
(
SrcFLo
->
getType
());
Variable
*
TLo
=
makeReg
(
SrcFLo
->
getType
());
_mov
(
TLo
,
SrcFLo
);
bool
RedefineTLo
=
false
;
Operand
*
SrcTLo
=
legalize
(
loOperand
(
SrcT
),
Legal_Reg
|
Legal_Flex
);
if
(
CondIfFalse
!=
CondARM32
::
kNone
)
{
_mov_redefined
(
TLo
,
SrcTLo
,
Cond
);
_mov
(
TLo
,
SrcFLo
,
CondIfFalse
);
RedefineTLo
=
true
;
}
if
(
CondIfTrue0
!=
CondARM32
::
kNone
)
{
if
(
!
RedefineTLo
)
_mov
(
TLo
,
SrcTLo
,
CondIfTrue0
);
else
_mov_redefined
(
TLo
,
SrcTLo
,
CondIfTrue0
);
RedefineTLo
=
true
;
}
if
(
CondIfTrue1
!=
CondARM32
::
kNone
)
{
assert
(
RedefineTLo
);
_mov_redefined
(
TLo
,
SrcTLo
,
CondIfTrue1
);
}
_mov
(
DestLo
,
TLo
);
_mov
(
DestLo
,
TLo
);
// Set the high portion.
// Set the high portion.
Variable
*
DestHi
=
llvm
::
cast
<
Variable
>
(
hiOperand
(
Dest
));
Variable
*
DestHi
=
llvm
::
cast
<
Variable
>
(
hiOperand
(
Dest
));
Operand
*
SrcTHi
=
legalize
(
hiOperand
(
SrcT
),
Legal_Reg
|
Legal_Flex
);
Operand
*
SrcFHi
=
legalize
(
hiOperand
(
SrcF
),
Legal_Reg
|
Legal_Flex
);
Operand
*
SrcFHi
=
legalize
(
hiOperand
(
SrcF
),
Legal_Reg
|
Legal_Flex
);
Variable
*
THi
=
makeReg
(
SrcFHi
->
getType
());
Variable
*
THi
=
makeReg
(
SrcFHi
->
getType
());
_mov
(
THi
,
SrcFHi
);
bool
RedefineTHi
=
false
;
Operand
*
SrcTHi
=
legalize
(
hiOperand
(
SrcT
),
Legal_Reg
|
Legal_Flex
);
if
(
CondIfFalse
!=
CondARM32
::
kNone
)
{
_mov_redefined
(
THi
,
SrcTHi
,
Cond
);
_mov
(
THi
,
SrcFHi
,
CondIfFalse
);
RedefineTHi
=
true
;
}
if
(
CondIfTrue0
!=
CondARM32
::
kNone
)
{
if
(
!
RedefineTHi
)
_mov
(
THi
,
SrcTHi
,
CondIfTrue0
);
else
_mov_redefined
(
THi
,
SrcTHi
,
CondIfTrue0
);
RedefineTHi
=
true
;
}
if
(
CondIfTrue1
!=
CondARM32
::
kNone
)
{
assert
(
RedefineTHi
);
_mov_redefined
(
THi
,
SrcTHi
,
CondIfTrue1
);
}
_mov
(
DestHi
,
THi
);
_mov
(
DestHi
,
THi
);
return
;
return
;
}
}
if
(
isFloatingType
(
DestTy
))
{
if
(
isFloatingType
(
DestTy
))
{
Variable
*
T
=
makeReg
(
DestTy
);
SrcT
=
legalizeToReg
(
SrcT
);
SrcF
=
legalizeToReg
(
SrcF
);
SrcF
=
legalizeToReg
(
SrcF
);
Variable
*
T
=
makeReg
(
DestTy
);
assert
(
DestTy
==
SrcF
->
getType
());
assert
(
DestTy
==
SrcF
->
getType
());
_mov
(
T
,
SrcF
);
bool
RedefineT
=
false
;
SrcT
=
legalizeToReg
(
SrcT
);
if
(
CondIfFalse
!=
CondARM32
::
kNone
)
{
_mov
(
T
,
SrcF
,
CondIfFalse
);
RedefineT
=
true
;
}
if
(
CondIfTrue0
!=
CondARM32
::
kNone
)
{
if
(
!
RedefineT
)
_mov
(
T
,
SrcT
,
CondIfTrue0
);
else
_mov_redefined
(
T
,
SrcT
,
CondIfTrue0
);
RedefineT
=
true
;
}
if
(
CondIfTrue1
!=
CondARM32
::
kNone
)
{
assert
(
RedefineT
);
_mov_redefined
(
T
,
SrcT
,
CondIfTrue1
);
}
assert
(
DestTy
==
SrcT
->
getType
());
assert
(
DestTy
==
SrcT
->
getType
());
_mov
(
T
,
SrcT
,
Cond
);
_set_dest_redefined
();
_mov
(
Dest
,
T
);
_mov
(
Dest
,
T
);
return
;
return
;
}
}
SrcF
=
legalize
(
SrcF
,
Legal_Reg
|
Legal_Flex
);
Variable
*
T
=
makeReg
(
SrcF
->
getType
());
Variable
*
T
=
makeReg
(
SrcF
->
getType
());
_mov
(
T
,
SrcF
);
SrcT
=
legalize
(
SrcT
,
Legal_Reg
|
Legal_Flex
);
SrcT
=
legalize
(
SrcT
,
Legal_Reg
|
Legal_Flex
);
_mov_redefined
(
T
,
SrcT
,
Cond
);
SrcF
=
legalize
(
SrcF
,
Legal_Reg
|
Legal_Flex
);
bool
RedefineT
=
false
;
if
(
CondIfFalse
!=
CondARM32
::
kNone
)
{
_mov
(
T
,
SrcF
,
CondIfFalse
);
RedefineT
=
true
;
}
if
(
CondIfTrue0
!=
CondARM32
::
kNone
)
{
if
(
!
RedefineT
)
_mov
(
T
,
SrcT
,
CondIfTrue0
);
else
_mov_redefined
(
T
,
SrcT
,
CondIfTrue0
);
RedefineT
=
true
;
}
if
(
CondIfTrue1
!=
CondARM32
::
kNone
)
{
assert
(
RedefineT
);
_mov_redefined
(
T
,
SrcT
,
CondIfTrue1
);
}
_mov
(
Dest
,
T
);
_mov
(
Dest
,
T
);
}
}
...
@@ -3786,6 +3958,126 @@ void TargetARM32::emit(const ConstantUndef *) const {
...
@@ -3786,6 +3958,126 @@ void TargetARM32::emit(const ConstantUndef *) const {
llvm
::
report_fatal_error
(
"undef value encountered by emitter."
);
llvm
::
report_fatal_error
(
"undef value encountered by emitter."
);
}
}
void
TargetARM32
::
lowerTruncToFlags
(
Operand
*
Src
,
CondARM32
::
Cond
*
CondIfTrue
,
CondARM32
::
Cond
*
CondIfFalse
)
{
Operand
*
_1
=
Ctx
->
getConstantInt32
(
1
);
Variable
*
SrcR
=
legalizeToReg
(
Src
->
getType
()
==
IceType_i64
?
loOperand
(
Src
)
:
Src
);
_tst
(
SrcR
,
_1
);
*
CondIfTrue
=
CondARM32
::
NE
;
// NE <-> APSR.Z == 0
*
CondIfFalse
=
CondARM32
::
EQ
;
// EQ <-> APSR.Z == 1
}
bool
TargetARM32
::
_mov_i1_to_flags
(
Operand
*
Boolean
,
CondARM32
::
Cond
*
CondIfTrue0
,
CondARM32
::
Cond
*
CondIfTrue1
,
CondARM32
::
Cond
*
CondIfFalse
)
{
*
CondIfTrue0
=
CondARM32
::
kNone
;
*
CondIfTrue1
=
CondARM32
::
kNone
;
*
CondIfFalse
=
CondARM32
::
AL
;
bool
FoldOK
=
false
;
if
(
const
Inst
*
Producer
=
BoolComputations
.
getProducerOf
(
Boolean
))
{
if
(
const
auto
*
IcmpProducer
=
llvm
::
dyn_cast
<
InstIcmp
>
(
Producer
))
{
lowerIcmpCond
(
IcmpProducer
,
CondIfTrue0
,
CondIfFalse
);
FoldOK
=
true
;
}
else
if
(
const
auto
*
FcmpProducer
=
llvm
::
dyn_cast
<
InstFcmp
>
(
Producer
))
{
lowerFcmpCond
(
FcmpProducer
,
CondIfTrue0
,
CondIfTrue1
,
CondIfFalse
);
FoldOK
=
true
;
}
else
if
(
const
auto
*
CastProducer
=
llvm
::
dyn_cast
<
InstCast
>
(
Producer
))
{
assert
(
CastProducer
->
getCastKind
()
==
InstCast
::
Trunc
);
lowerTruncToFlags
(
CastProducer
->
getSrc
(
0
),
CondIfTrue0
,
CondIfFalse
);
FoldOK
=
true
;
}
}
return
FoldOK
;
}
namespace
{
namespace
BoolFolding
{
bool
shouldTrackProducer
(
const
Inst
&
Instr
)
{
switch
(
static_cast
<
uint32_t
>
(
Instr
.
getKind
()))
{
case
Inst
:
:
Icmp
:
return
true
;
case
Inst
:
:
Fcmp
:
return
true
;
}
if
(
const
auto
*
Cast
=
llvm
::
dyn_cast
<
InstCast
>
(
&
Instr
))
{
switch
(
static_cast
<
uint32_t
>
(
Cast
->
getCastKind
()))
{
case
InstCast
:
:
Trunc
:
return
true
;
}
}
return
false
;
}
bool
isValidConsumer
(
const
Inst
&
Instr
)
{
switch
(
static_cast
<
uint32_t
>
(
Instr
.
getKind
()))
{
case
Inst
:
:
Br
:
return
true
;
case
Inst
:
:
Select
:
return
!
isVectorType
(
Instr
.
getDest
()
->
getType
());
}
if
(
const
auto
*
Cast
=
llvm
::
dyn_cast
<
InstCast
>
(
&
Instr
))
{
switch
(
static_cast
<
uint32_t
>
(
Cast
->
getCastKind
()))
{
case
InstCast
:
:
Sext
:
return
!
isVectorType
(
Instr
.
getDest
()
->
getType
());
case
InstCast
:
:
Zext
:
return
!
isVectorType
(
Instr
.
getDest
()
->
getType
());
}
}
return
false
;
}
}
// end of namespace BoolFolding
}
// end of anonymous namespace
void
TargetARM32
::
BoolComputationTracker
::
recordProducers
(
CfgNode
*
Node
)
{
for
(
Inst
&
Instr
:
Node
->
getInsts
())
{
// Check whether Instr is a valid producer.
Variable
*
Dest
=
Instr
.
getDest
();
if
(
!
Instr
.
isDeleted
()
// only consider non-deleted instructions; and
&&
Dest
// only instructions with an actual dest var; and
&&
Dest
->
getType
()
==
IceType_i1
// only bool-type dest vars; and
&&
BoolFolding
::
shouldTrackProducer
(
Instr
))
{
// white-listed instr.
KnownComputations
.
emplace
(
Dest
->
getIndex
(),
BoolComputationEntry
(
&
Instr
));
}
// Check each src variable against the map.
FOREACH_VAR_IN_INST
(
Var
,
Instr
)
{
SizeT
VarNum
=
Var
->
getIndex
();
auto
ComputationIter
=
KnownComputations
.
find
(
VarNum
);
if
(
ComputationIter
==
KnownComputations
.
end
())
{
continue
;
}
if
(
IndexOfVarOperandInInst
(
Var
)
!=
0
||
!
BoolFolding
::
isValidConsumer
(
Instr
))
{
// All valid consumers use Var as the first source operand
KnownComputations
.
erase
(
VarNum
);
continue
;
}
if
(
Instr
.
isLastUse
(
Var
))
{
ComputationIter
->
second
.
IsLiveOut
=
false
;
}
}
}
for
(
auto
Iter
=
KnownComputations
.
begin
(),
End
=
KnownComputations
.
end
();
Iter
!=
End
;)
{
// Disable the folding if its dest may be live beyond this block.
if
(
Iter
->
second
.
IsLiveOut
)
{
Iter
=
KnownComputations
.
erase
(
Iter
);
continue
;
}
// Mark as "dead" rather than outright deleting. This is so that other
// peephole style optimizations during or before lowering have access to
// this instruction in undeleted form. See for example
// tryOptimizedCmpxchgCmpBr().
Iter
->
second
.
Instr
->
setDead
();
++
Iter
;
}
}
TargetDataARM32
::
TargetDataARM32
(
GlobalContext
*
Ctx
)
TargetDataARM32
::
TargetDataARM32
(
GlobalContext
*
Ctx
)
:
TargetDataLowering
(
Ctx
)
{}
:
TargetDataLowering
(
Ctx
)
{}
...
...
src/IceTargetLoweringARM32.h
View file @
4a5e6d05
...
@@ -58,6 +58,12 @@ public:
...
@@ -58,6 +58,12 @@ public:
// TODO(jvoung): return a unique_ptr.
// TODO(jvoung): return a unique_ptr.
static
TargetARM32
*
create
(
Cfg
*
Func
)
{
return
new
TargetARM32
(
Func
);
}
static
TargetARM32
*
create
(
Cfg
*
Func
)
{
return
new
TargetARM32
(
Func
);
}
void
initNodeForLowering
(
CfgNode
*
Node
)
override
{
BoolComputations
.
forgetProducers
();
BoolComputations
.
recordProducers
(
Node
);
BoolComputations
.
dump
(
Func
);
}
void
translateOm1
()
override
;
void
translateOm1
()
override
;
void
translateO2
()
override
;
void
translateO2
()
override
;
bool
doBranchOpt
(
Inst
*
I
,
const
CfgNode
*
NextNode
)
override
;
bool
doBranchOpt
(
Inst
*
I
,
const
CfgNode
*
NextNode
)
override
;
...
@@ -130,8 +136,13 @@ protected:
...
@@ -130,8 +136,13 @@ protected:
void
lowerCall
(
const
InstCall
*
Inst
)
override
;
void
lowerCall
(
const
InstCall
*
Inst
)
override
;
void
lowerCast
(
const
InstCast
*
Inst
)
override
;
void
lowerCast
(
const
InstCast
*
Inst
)
override
;
void
lowerExtractElement
(
const
InstExtractElement
*
Inst
)
override
;
void
lowerExtractElement
(
const
InstExtractElement
*
Inst
)
override
;
void
lowerFcmp
(
const
InstFcmp
*
Inst
)
override
;
void
lowerFcmpCond
(
const
InstFcmp
*
Instr
,
CondARM32
::
Cond
*
CondIfTrue0
,
void
lowerIcmp
(
const
InstIcmp
*
Inst
)
override
;
CondARM32
::
Cond
*
CondIfTrue1
,
CondARM32
::
Cond
*
CondIfFalse
);
void
lowerFcmp
(
const
InstFcmp
*
Instr
)
override
;
void
lowerIcmpCond
(
const
InstIcmp
*
Instr
,
CondARM32
::
Cond
*
CondIfTrue
,
CondARM32
::
Cond
*
CondIfFalse
);
void
lowerIcmp
(
const
InstIcmp
*
Instr
)
override
;
void
lowerAtomicRMW
(
Variable
*
Dest
,
uint32_t
Operation
,
Operand
*
Ptr
,
void
lowerAtomicRMW
(
Variable
*
Dest
,
uint32_t
Operation
,
Operand
*
Ptr
,
Operand
*
Val
);
Operand
*
Val
);
void
lowerIntrinsicCall
(
const
InstIntrinsicCall
*
Inst
)
override
;
void
lowerIntrinsicCall
(
const
InstIntrinsicCall
*
Inst
)
override
;
...
@@ -316,6 +327,60 @@ protected:
...
@@ -316,6 +327,60 @@ protected:
Context
.
insert
(
InstFakeDef
::
create
(
Func
,
Instr
->
getDestHi
()));
Context
.
insert
(
InstFakeDef
::
create
(
Func
,
Instr
->
getDestHi
()));
}
}
}
}
// _mov_i1_to_flags is used for bool folding. If "Boolean" is folded, this
// method returns true, and sets "CondIfTrue0" and "CondIfTrue1" to the
// appropriate ARM condition codes. If "Boolean" is not to be folded, then this
// method returns false.
bool
_mov_i1_to_flags
(
Operand
*
Boolean
,
CondARM32
::
Cond
*
CondIfTrue0
,
CondARM32
::
Cond
*
CondIfTrue1
,
CondARM32
::
Cond
*
CondIfFalse
);
// _cmov is a pseudo instruction that is used for boolean folding. It emits
// code that moves "SrcIfTrue" to dest if either "CondIfTrue0" or
// "CondIfTrue1" holds, and "SrcIfFalse", if "CondIfFalse" holds. It requires
// "Dest" to be an infinite-weight temporary.
void
_cmov
(
Variable
*
Dest
,
Operand
*
SrcIfTrue
,
CondARM32
::
Cond
CondIfTrue0
,
CondARM32
::
Cond
CondIfTrue1
,
Operand
*
SrcIfFalse
,
CondARM32
::
Cond
CondIfFalse
)
{
assert
(
Dest
->
mustHaveReg
());
if
(
CondIfFalse
==
CondARM32
::
kNone
)
{
assert
(
CondIfTrue0
==
CondARM32
::
AL
);
assert
(
CondIfTrue1
==
CondARM32
::
kNone
);
}
if
(
CondIfTrue0
==
CondARM32
::
kNone
)
{
assert
(
CondIfFalse
==
CondARM32
::
AL
);
assert
(
CondIfTrue1
==
CondARM32
::
kNone
);
}
if
(
CondIfTrue1
!=
CondARM32
::
kNone
)
{
assert
(
CondIfFalse
==
CondARM32
::
AL
);
assert
(
CondIfTrue1
!=
CondARM32
::
kNone
);
}
bool
RedefineT
=
false
;
if
(
CondIfFalse
!=
CondARM32
::
kNone
)
{
_mov
(
Dest
,
SrcIfFalse
,
CondIfFalse
);
RedefineT
=
true
;
}
if
(
CondIfTrue0
!=
CondARM32
::
kNone
)
{
if
(
RedefineT
)
{
_mov_redefined
(
Dest
,
SrcIfTrue
,
CondIfTrue0
);
}
else
{
_mov
(
Dest
,
SrcIfTrue
,
CondIfTrue0
);
}
RedefineT
=
true
;
}
if
(
CondIfTrue1
!=
CondARM32
::
kNone
)
{
assert
(
RedefineT
);
_mov_redefined
(
Dest
,
SrcIfTrue
,
CondIfTrue1
);
}
}
/// The Operand can only be a 16-bit immediate or a ConstantRelocatable (with
/// The Operand can only be a 16-bit immediate or a ConstantRelocatable (with
/// an upper16 relocation).
/// an upper16 relocation).
void
_movt
(
Variable
*
Dest
,
Operand
*
Src0
,
void
_movt
(
Variable
*
Dest
,
Operand
*
Src0
,
...
@@ -542,6 +607,64 @@ protected:
...
@@ -542,6 +607,64 @@ protected:
private
:
private
:
~
TargetARM32
()
override
=
default
;
~
TargetARM32
()
override
=
default
;
void
lowerTruncToFlags
(
Operand
*
Src
,
CondARM32
::
Cond
*
CondIfTrue
,
CondARM32
::
Cond
*
CondIfFalse
);
class
BoolComputationTracker
{
public
:
BoolComputationTracker
()
=
default
;
~
BoolComputationTracker
()
=
default
;
void
forgetProducers
()
{
KnownComputations
.
clear
();
}
void
recordProducers
(
CfgNode
*
Node
);
const
Inst
*
getProducerOf
(
const
Operand
*
Opnd
)
const
{
auto
*
Var
=
llvm
::
dyn_cast
<
Variable
>
(
Opnd
);
if
(
Var
==
nullptr
)
{
return
nullptr
;
}
auto
Iter
=
KnownComputations
.
find
(
Var
->
getIndex
());
if
(
Iter
==
KnownComputations
.
end
())
{
return
nullptr
;
}
return
Iter
->
second
.
Instr
;
}
void
dump
(
const
Cfg
*
Func
)
const
{
if
(
!
BuildDefs
::
dump
()
||
!
Func
->
isVerbose
(
IceV_Folding
))
return
;
OstreamLocker
L
(
Func
->
getContext
());
Ostream
&
Str
=
Func
->
getContext
()
->
getStrDump
();
Str
<<
"foldable producer:
\n
"
;
for
(
const
auto
&
Computation
:
KnownComputations
)
{
Str
<<
" "
;
Computation
.
second
.
Instr
->
dump
(
Func
);
Str
<<
"
\n
"
;
}
Str
<<
"
\n
"
;
}
private
:
class
BoolComputationEntry
{
public
:
explicit
BoolComputationEntry
(
Inst
*
I
)
:
Instr
(
I
)
{}
Inst
*
const
Instr
;
// Boolean folding is disabled for variables whose live range is multi
// block. We conservatively initialize IsLiveOut to true, and set it to
// false once we find the end of the live range for the variable defined
// by this instruction. If liveness analysis is not performed (e.g., in
// Om1 mode) IsLiveOut will never be set to false, and folding will be
// disabled.
bool
IsLiveOut
=
true
;
};
using
BoolComputationMap
=
std
::
unordered_map
<
SizeT
,
BoolComputationEntry
>
;
BoolComputationMap
KnownComputations
;
};
BoolComputationTracker
BoolComputations
;
};
};
class
TargetDataARM32
final
:
public
TargetDataLowering
{
class
TargetDataARM32
final
:
public
TargetDataLowering
{
...
...
tests_lit/assembler/arm32/branch-mult-fwd.ll
View file @
4a5e6d05
...
@@ -53,40 +53,40 @@ define internal void @mult_fwd_branches(i32 %a, i32 %b) {
...
@@ -53,40 +53,40 @@ define internal void @mult_fwd_branches(i32 %a, i32 %b) {
%cmp
=
icmp
slt
i32
%a
,
%b
%cmp
=
icmp
slt
i32
%a
,
%b
; ASM-NEXT: ldr r0, [sp, #8]
; ASM-NEXT: ldr r0, [sp, #8]
; ASM-NEXT:
mov r1, #0
; ASM-NEXT:
ldr r1, [sp, #4]
; ASM-NEXT:
ldr r2, [sp, #4]
; ASM-NEXT:
cmp r0, r1
; ASM-NEXT:
cmp r0, r2
; ASM-NEXT:
movge r0, #0
; ASM-NEXT: movlt r
1
, #1
; ASM-NEXT: movlt r
0
, #1
; ASM-NEXT: str r
1
, [sp]
; ASM-NEXT: str r
0
, [sp]
; DIS-NEXT: c: e59d0008
; DIS-NEXT: c: e59d0008
; DIS-NEXT: 10: e
3a01000
; DIS-NEXT: 10: e
59d1004
; DIS-NEXT: 14: e
59d2004
; DIS-NEXT: 14: e
1500001
; DIS-NEXT: 18:
e1500002
; DIS-NEXT: 18:
a3a00000
; DIS-NEXT: 1c: b3a0
1
001
; DIS-NEXT: 1c: b3a0
0
001
; DIS-NEXT: 20: e58d
1
000
; DIS-NEXT: 20: e58d
0
000
; IASM-NEXT: .byte 0x8
; IASM-NEXT: .byte 0x8
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x9d
; IASM-NEXT: .byte 0x9d
; IASM-NEXT: .byte 0xe5
; IASM-NEXT: .byte 0xe5
; IASM-NEXT: mov r1, #0
; IASM-NEXT: .byte 0x4
; IASM-NEXT: .byte 0x4
; IASM-NEXT: .byte 0x
2
0
; IASM-NEXT: .byte 0x
1
0
; IASM-NEXT: .byte 0x9d
; IASM-NEXT: .byte 0x9d
; IASM-NEXT: .byte 0xe5
; IASM-NEXT: .byte 0xe5
; IASM-NEXT: .byte 0x
2
; IASM-NEXT: .byte 0x
1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x50
; IASM-NEXT: .byte 0x50
; IASM-NEXT: .byte 0xe1
; IASM-NEXT: .byte 0xe1
; IASM-NEXT: movlt r1, #1
; IASM-NEXT: movge r0, #0
; IASM-NEXT: movlt r0, #1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x
1
0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x8d
; IASM-NEXT: .byte 0x8d
; IASM-NEXT: .byte 0xe5
; IASM-NEXT: .byte 0xe5
...
...
tests_lit/llvm2ice_tests/64bit.pnacl.ll
View file @
4a5e6d05
...
@@ -18,13 +18,13 @@
...
@@ -18,13 +18,13 @@
; RUN: --disassemble --target arm32 -i %s --args -O2 --skip-unimplemented \
; RUN: --disassemble --target arm32 -i %s --args -O2 --skip-unimplemented \
; RUN: -allow-externally-defined-symbols \
; RUN: -allow-externally-defined-symbols \
; 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-O2
%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 -Om1 --skip-unimplemented \
; RUN: -i %s --args -Om1 --skip-unimplemented \
; RUN: -allow-externally-defined-symbols \
; RUN: -allow-externally-defined-symbols \
; 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-OM1
%s
@__init_array_start
=
internal
constant
[
0
x
i8
]
zeroinitializer
,
align
4
@__init_array_start
=
internal
constant
[
0
x
i8
]
zeroinitializer
,
align
4
@__fini_array_start
=
internal
constant
[
0
x
i8
]
zeroinitializer
,
align
4
@__fini_array_start
=
internal
constant
[
0
x
i8
]
zeroinitializer
,
align
4
...
@@ -849,8 +849,11 @@ entry:
...
@@ -849,8 +849,11 @@ entry:
; OPTM1-NOT: and eax,0x1
; OPTM1-NOT: and eax,0x1
; ARM32-LABEL: trunc64To1
; ARM32-LABEL: trunc64To1
; ARM32: and r0, r0, #1
; ARM32-OM1: and r0, r0, #1
; ARM32: and r0, r0, #1
; ARM32-OM1: and r0, r0, #1
; ARM32-O2: tst r0, #1
; ARM32-O2: moveq [[RES:r[0-9]+]], #0
; ARM32-O2: movne [[RES]], #1
define
internal
i64
@sext32To64
(
i32
%a
)
{
define
internal
i64
@sext32To64
(
i32
%a
)
{
entry:
entry:
...
@@ -921,8 +924,12 @@ entry:
...
@@ -921,8 +924,12 @@ entry:
; OPTM1: sar {{.*}},0x1f
; OPTM1: sar {{.*}},0x1f
; ARM32-LABEL: sext1To64
; ARM32-LABEL: sext1To64
; ARM32: lsl {{.*}}, #31
; ARM32-OM1: lsl {{.*}}, #31
; ARM32: asr {{.*}}, #31
; ARM32-OM1: asr {{.*}}, #31
; ARM32-O2: tst r0, #1
; ARM32-O2: mvn [[M1:r[0-9]+]], #0
; ARM32-O2: moveq [[RES:r[0-9]+]], #0
; ARM32-O2: movne [[RES]], [[M1]]
define
internal
i64
@zext32To64
(
i32
%a
)
{
define
internal
i64
@zext32To64
(
i32
%a
)
{
entry:
entry:
...
@@ -991,8 +998,11 @@ entry:
...
@@ -991,8 +998,11 @@ entry:
; OPTM1: mov {{.*}},0x0
; OPTM1: mov {{.*}},0x0
; ARM32-LABEL: zext1To64
; ARM32-LABEL: zext1To64
; ARM32: and {{.*}}, #1
; ARM32-OM1: and {{.*}}, #1
; ARM32: mov {{.*}}, #0
; ARM32-OM1: mov {{.*}}, #0
; ARM32-O2: tst r0, #1
; ARM32-O2: moveq {{[^,]*}}, #0
; ARM32-O2: movne {{[^,]*}}, #1
define
internal
void
@icmpEq64
(
i64
%a
,
i64
%b
,
i64
%c
,
i64
%d
)
{
define
internal
void
@icmpEq64
(
i64
%a
,
i64
%b
,
i64
%c
,
i64
%d
)
{
entry:
entry:
...
@@ -1051,13 +1061,17 @@ if.end3: ; preds = %if.then2, %if.end
...
@@ -1051,13 +1061,17 @@ if.end3: ; preds = %if.then2, %if.end
; ARM32-LABEL: icmpEq64
; ARM32-LABEL: icmpEq64
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32: moveq
; ARM32-OM1: movne
; ARM32: movne
; ARM32-OM1: moveq
; ARM32-OM1: cmp
; ARM32-O2: bne
; ARM32: bl
; ARM32: bl
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32: moveq
; ARM32-OM1: movne
; ARM32: movne
; ARM32-OM1: moveq
; ARM32-OM1: cmp
; ARM32-O2: bne
; ARM32: bl
; ARM32: bl
declare
void
@func
()
declare
void
@func
()
...
@@ -1119,13 +1133,17 @@ if.end3: ; preds = %if.end, %if.then2
...
@@ -1119,13 +1133,17 @@ if.end3: ; preds = %if.end, %if.then2
; ARM32-LABEL: icmpNe64
; ARM32-LABEL: icmpNe64
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32: movne
; ARM32-OM1: moveq
; ARM32: moveq
; ARM32-OM1: movne
; ARM32-OM1: cmp
; ARM32-O2: beq
; ARM32: bl
; ARM32: bl
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32: movne
; ARM32-OM1: moveq
; ARM32: moveq
; ARM32-OM1: movne
; ARM32-OM1: cmp
; ARM32-O2: beq
; ARM32: bl
; ARM32: bl
define
internal
void
@icmpGt64
(
i64
%a
,
i64
%b
,
i64
%c
,
i64
%d
)
{
define
internal
void
@icmpGt64
(
i64
%a
,
i64
%b
,
i64
%c
,
i64
%d
)
{
...
@@ -1171,13 +1189,17 @@ if.end3: ; preds = %if.then2, %if.end
...
@@ -1171,13 +1189,17 @@ if.end3: ; preds = %if.then2, %if.end
; ARM32-LABEL: icmpGt64
; ARM32-LABEL: icmpGt64
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32: movhi
; ARM32-OM1: movls
; ARM32: movls
; ARM32-OM1: movhi
; ARM32-OM1: cmp
; ARM32-O2: bls
; ARM32: bl
; ARM32: bl
; ARM32: cmp
; ARM32: cmp
; ARM32: sbcs
; ARM32: sbcs
; ARM32: movlt
; ARM32-OM1: movge
; ARM32: movge
; ARM32-OM1: movlt
; ARM32-OM1: cmp
; ARM32-O2: bge
; ARM32: bl
; ARM32: bl
define
internal
void
@icmpGe64
(
i64
%a
,
i64
%b
,
i64
%c
,
i64
%d
)
{
define
internal
void
@icmpGe64
(
i64
%a
,
i64
%b
,
i64
%c
,
i64
%d
)
{
...
@@ -1223,13 +1245,17 @@ if.end3: ; preds = %if.end, %if.then2
...
@@ -1223,13 +1245,17 @@ if.end3: ; preds = %if.end, %if.then2
; ARM32-LABEL: icmpGe64
; ARM32-LABEL: icmpGe64
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32: movcs
; ARM32-OM1: movcc
; ARM32: movcc
; ARM32-OM1: movcs
; ARM32-OM1: cmp
; ARM32-O2: bcc
; ARM32: bl
; ARM32: bl
; ARM32: cmp
; ARM32: cmp
; ARM32: sbcs
; ARM32: sbcs
; ARM32: movge
; ARM32-OM1: movlt
; ARM32: movlt
; ARM32-OM1: movge
; ARM32-OM1: cmp
; ARM32-O2: blt
; ARM32: bl
; ARM32: bl
define
internal
void
@icmpLt64
(
i64
%a
,
i64
%b
,
i64
%c
,
i64
%d
)
{
define
internal
void
@icmpLt64
(
i64
%a
,
i64
%b
,
i64
%c
,
i64
%d
)
{
...
@@ -1275,13 +1301,17 @@ if.end3: ; preds = %if.then2, %if.end
...
@@ -1275,13 +1301,17 @@ if.end3: ; preds = %if.then2, %if.end
; ARM32-LABEL: icmpLt64
; ARM32-LABEL: icmpLt64
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32: movcc
; ARM32-OM1: movcs
; ARM32: movcs
; ARM32-OM1: movcc
; ARM32-OM1: cmp
; ARM32-O2: bcs
; ARM32: bl
; ARM32: bl
; ARM32: cmp
; ARM32: cmp
; ARM32: sbcs
; ARM32: sbcs
; ARM32: movlt
; ARM32-OM1: movge
; ARM32: movge
; ARM32-OM1: movlt
; ARM32-OM1: cmp
; ARM32-O2: bge
; ARM32: bl
; ARM32: bl
define
internal
void
@icmpLe64
(
i64
%a
,
i64
%b
,
i64
%c
,
i64
%d
)
{
define
internal
void
@icmpLe64
(
i64
%a
,
i64
%b
,
i64
%c
,
i64
%d
)
{
...
@@ -1327,13 +1357,16 @@ if.end3: ; preds = %if.end, %if.then2
...
@@ -1327,13 +1357,16 @@ if.end3: ; preds = %if.end, %if.then2
; ARM32-LABEL: icmpLe64
; ARM32-LABEL: icmpLe64
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32: movls
; ARM32-OM1: movhi
; ARM32: movhi
; ARM32-OM1: movls
; ARM32-OM1: cmp
; ARM32-O2: bhi
; ARM32: bl
; ARM32: bl
; ARM32: cmp
; ARM32: cmp
; ARM32: sbcs
; ARM32: sbcs
; ARM32: movge
; ARM32-OM1: movlt
; ARM32: movlt
; ARM32-OM1: movge
; ARM32-O2: blt
; ARM32: bl
; ARM32: bl
define
internal
i32
@icmpEq64Bool
(
i64
%a
,
i64
%b
)
{
define
internal
i32
@icmpEq64Bool
(
i64
%a
,
i64
%b
)
{
...
@@ -1351,8 +1384,8 @@ entry:
...
@@ -1351,8 +1384,8 @@ entry:
; OPTM1: je
; OPTM1: je
; ARM32-LABEL: icmpEq64Bool
; ARM32-LABEL: icmpEq64Bool
; ARM32: moveq
; ARM32: movne
; ARM32: movne
; ARM32: moveq
define
internal
i32
@icmpNe64Bool
(
i64
%a
,
i64
%b
)
{
define
internal
i32
@icmpNe64Bool
(
i64
%a
,
i64
%b
)
{
entry:
entry:
...
@@ -1369,8 +1402,8 @@ entry:
...
@@ -1369,8 +1402,8 @@ entry:
; OPTM1: jne
; OPTM1: jne
; ARM32-LABEL: icmpNe64Bool
; ARM32-LABEL: icmpNe64Bool
; ARM32: movne
; ARM32: moveq
; ARM32: moveq
; ARM32: movne
define
internal
i32
@icmpSgt64Bool
(
i64
%a
,
i64
%b
)
{
define
internal
i32
@icmpSgt64Bool
(
i64
%a
,
i64
%b
)
{
entry:
entry:
...
@@ -1395,8 +1428,8 @@ entry:
...
@@ -1395,8 +1428,8 @@ entry:
; ARM32-LABEL: icmpSgt64Bool
; ARM32-LABEL: icmpSgt64Bool
; ARM32: cmp
; ARM32: cmp
; ARM32: sbcs
; ARM32: sbcs
; ARM32: movlt
; ARM32: movge
; ARM32: movge
; ARM32: movlt
define
internal
i32
@icmpUgt64Bool
(
i64
%a
,
i64
%b
)
{
define
internal
i32
@icmpUgt64Bool
(
i64
%a
,
i64
%b
)
{
entry:
entry:
...
@@ -1421,8 +1454,8 @@ entry:
...
@@ -1421,8 +1454,8 @@ entry:
; ARM32-LABEL: icmpUgt64Bool
; ARM32-LABEL: icmpUgt64Bool
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32: movhi
; ARM32: movls
; ARM32: movls
; ARM32: movhi
define
internal
i32
@icmpSge64Bool
(
i64
%a
,
i64
%b
)
{
define
internal
i32
@icmpSge64Bool
(
i64
%a
,
i64
%b
)
{
entry:
entry:
...
@@ -1447,8 +1480,8 @@ entry:
...
@@ -1447,8 +1480,8 @@ entry:
; ARM32-LABEL: icmpSge64Bool
; ARM32-LABEL: icmpSge64Bool
; ARM32: cmp
; ARM32: cmp
; ARM32: sbcs
; ARM32: sbcs
; ARM32: movge
; ARM32: movlt
; ARM32: movlt
; ARM32: movge
define
internal
i32
@icmpUge64Bool
(
i64
%a
,
i64
%b
)
{
define
internal
i32
@icmpUge64Bool
(
i64
%a
,
i64
%b
)
{
entry:
entry:
...
@@ -1473,8 +1506,8 @@ entry:
...
@@ -1473,8 +1506,8 @@ entry:
; ARM32-LABEL: icmpUge64Bool
; ARM32-LABEL: icmpUge64Bool
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32: movcs
; ARM32: movcc
; ARM32: movcc
; ARM32: movcs
define
internal
i32
@icmpSlt64Bool
(
i64
%a
,
i64
%b
)
{
define
internal
i32
@icmpSlt64Bool
(
i64
%a
,
i64
%b
)
{
entry:
entry:
...
@@ -1499,8 +1532,8 @@ entry:
...
@@ -1499,8 +1532,8 @@ entry:
; ARM32-LABEL: icmpSlt64Bool
; ARM32-LABEL: icmpSlt64Bool
; ARM32: cmp
; ARM32: cmp
; ARM32: sbcs
; ARM32: sbcs
; ARM32: movlt
; ARM32: movge
; ARM32: movge
; ARM32: movlt
define
internal
i32
@icmpUlt64Bool
(
i64
%a
,
i64
%b
)
{
define
internal
i32
@icmpUlt64Bool
(
i64
%a
,
i64
%b
)
{
entry:
entry:
...
@@ -1525,8 +1558,8 @@ entry:
...
@@ -1525,8 +1558,8 @@ entry:
; ARM32-LABEL: icmpUlt64Bool
; ARM32-LABEL: icmpUlt64Bool
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32: movcc
; ARM32: movcs
; ARM32: movcs
; ARM32: movcc
define
internal
i32
@icmpSle64Bool
(
i64
%a
,
i64
%b
)
{
define
internal
i32
@icmpSle64Bool
(
i64
%a
,
i64
%b
)
{
entry:
entry:
...
@@ -1551,8 +1584,8 @@ entry:
...
@@ -1551,8 +1584,8 @@ entry:
; ARM32-LABEL: icmpSle64Bool
; ARM32-LABEL: icmpSle64Bool
; ARM32: cmp
; ARM32: cmp
; ARM32: sbcs
; ARM32: sbcs
; ARM32: movge
; ARM32: movlt
; ARM32: movlt
; ARM32: movge
define
internal
i32
@icmpUle64Bool
(
i64
%a
,
i64
%b
)
{
define
internal
i32
@icmpUle64Bool
(
i64
%a
,
i64
%b
)
{
entry:
entry:
...
@@ -1577,8 +1610,8 @@ entry:
...
@@ -1577,8 +1610,8 @@ entry:
; ARM32-LABEL: icmpUle64Bool
; ARM32-LABEL: icmpUle64Bool
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32: movls
; ARM32: movhi
; ARM32: movhi
; ARM32: movls
define
internal
i64
@load64
(
i32
%a
)
{
define
internal
i64
@load64
(
i32
%a
)
{
entry:
entry:
...
@@ -1666,15 +1699,15 @@ entry:
...
@@ -1666,15 +1699,15 @@ entry:
; OPTM1: cmovne
; OPTM1: cmovne
; ARM32-LABEL: select64VarVar
; ARM32-LABEL: select64VarVar
; The initial compare.
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32: movcc
; ARM32-OM1: movcs
; ARM32: movcs
; ARM32-OM1: movcc
; The non-folded compare for the select.
; ARM32-OM1: cmp
; ARM32: cmp
; ARM32-OM1: movne
; ARM32: movne
; ARM32-O2: movcc
; ARM32: movne
; ARM32-OM1: movne
; ARM32-O2: movcc
define
internal
i64
@select64VarConst
(
i64
%a
,
i64
%b
)
{
define
internal
i64
@select64VarConst
(
i64
%a
,
i64
%b
)
{
entry:
entry:
...
@@ -1703,15 +1736,17 @@ entry:
...
@@ -1703,15 +1736,17 @@ entry:
; ARM32-LABEL: select64VarConst
; ARM32-LABEL: select64VarConst
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32
: movcc
; ARM32
-OM1: movcs
; ARM32
: movcs
; ARM32
-OM1: movcc
; ARM32: cmp
; ARM32
-OM1
: cmp
; ARM32: movw
; ARM32: movw
; ARM32: movt
; ARM32: movt
; ARM32: movne
; ARM32-OM1: movne
; ARM32-O2: movcc
; ARM32: movw
; ARM32: movw
; ARM32: movt
; ARM32: movt
; ARM32: movne
; ARM32-OM1: movne
; ARM32-O2: movcc
define
internal
i64
@select64ConstVar
(
i64
%a
,
i64
%b
)
{
define
internal
i64
@select64ConstVar
(
i64
%a
,
i64
%b
)
{
entry:
entry:
...
@@ -1740,15 +1775,17 @@ entry:
...
@@ -1740,15 +1775,17 @@ entry:
; ARM32-LABEL: select64ConstVar
; ARM32-LABEL: select64ConstVar
; ARM32: cmp
; ARM32: cmp
; ARM32: cmpeq
; ARM32: cmpeq
; ARM32
: movcc
; ARM32
-OM1: movcs
; ARM32
: movcs
; ARM32
-OM1: movcc
; ARM32: cmp
; ARM32
-OM1
: cmp
; ARM32: movw
; ARM32: movw
; ARM32: movt
; ARM32: movt
; ARM32: movne
; ARM32-OM1: movne
; ARM32-O2: movcc
; ARM32: movw
; ARM32: movw
; ARM32: movt
; ARM32: movt
; ARM32: movne
; ARM32-OM1: movne
; ARM32-O2: movcc
define
internal
void
@icmpEq64Imm
()
{
define
internal
void
@icmpEq64Imm
()
{
entry:
entry:
...
...
tests_lit/llvm2ice_tests/bool-folding.ll
View file @
4a5e6d05
...
@@ -28,8 +28,12 @@ branch2:
...
@@ -28,8 +28,12 @@ branch2:
; CHECK: cmp
; CHECK: cmp
; CHECK: jge
; CHECK: jge
; ARM32-LABEL: fold_cmp_br
; ARM32-LABEL: fold_cmp_br
; ARM32: cmp
; ARM32: cmp r0, r1
; ARM32: beq
; ARM32: bge
; ARM32: mov r0, #1
; ARM32: bx lr
; ARM32: mov r0, #2
; ARM32: bx lr
; Cmp/branch folding with intervening instructions.
; Cmp/branch folding with intervening instructions.
...
@@ -51,11 +55,13 @@ branch2:
...
@@ -51,11 +55,13 @@ branch2:
; CHECK: jge
; CHECK: jge
; ARM32-LABEL: fold_cmp_br_intervening_insts
; ARM32-LABEL: fold_cmp_br_intervening_insts
; ARM32: push {{[{].*[}]}}
; ARM32: push {{[{].*[}]}}
; ARM32: movlt [[TMP:r[0-9]+]], #1
; ARM32: bl use_value
; ARM32: mov [[P:r[4-7]]], [[TMP]]
; ARM32: cmp {{r[0-9]+}}, {{r[0-9]+}}
; ARM32: bl
; ARM32: bge
; ARM32: cmp [[P]], #0
; ARM32: mov r0, #1
; ARM32: beq
; ARM32: bx lr
; ARM32: mov r0, #2
; ARM32: bx lr
; Cmp/branch non-folding because of live-out.
; Cmp/branch non-folding because of live-out.
...
@@ -102,13 +108,14 @@ branch2:
...
@@ -102,13 +108,14 @@ branch2:
; CHECK: cmp
; CHECK: cmp
; CHECK: je
; CHECK: je
; ARM32-LABEL: no_fold_cmp_br_non_whitelist
; ARM32-LABEL: no_fold_cmp_br_non_whitelist
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: cmp r0, r1
; ARM32: cmp r0, r1
; ARM32: movge [[R:r[0-9]+]], #0
; ARM32: movlt [[R]], #1
; ARM32: movlt [[R]], #1
; ARM32: mov [[R2:r[0-9]+]], [[R]]
; ARM32: cmp r0, r1
; ARM32: and [[R3:r[0-9]+]], [[R2]], #1
; ARM32: bge
; ARM32: cmp [[R]]
; ARM32: bx lr
; ARM32: beq
; ARM32: mov r0, #2
; ARM32: bx lr
; Basic cmp/select folding.
; Basic cmp/select folding.
...
@@ -123,11 +130,8 @@ entry:
...
@@ -123,11 +130,8 @@ entry:
; CHECK: cmp
; CHECK: cmp
; CHECK: cmovl
; CHECK: cmovl
; ARM32-LABEL: fold_cmp_select
; ARM32-LABEL: fold_cmp_select
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: cmp r0, r1
; ARM32: cmp r0, r1
; ARM32: movlt [[R]], #1
; ARM32: movlt {{r[0-9]+}}, r0
; ARM32: cmp [[R]], #0
; 64-bit cmp/select folding.
; 64-bit cmp/select folding.
define
internal
i64
@fold_cmp_select_64
(
i64
%arg1
,
i64
%arg2
)
{
define
internal
i64
@fold_cmp_select_64
(
i64
%arg1
,
i64
%arg2
)
{
...
@@ -144,14 +148,11 @@ entry:
...
@@ -144,14 +148,11 @@ entry:
; CHECK: cmovl
; CHECK: cmovl
; CHECK: cmovl
; CHECK: cmovl
; ARM32-LABEL: fold_cmp_select_64
; ARM32-LABEL: fold_cmp_select_64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: cmp r0, r2
; ARM32: cmp r0, r2
; ARM32: movlt [[R]], #1
; ARM32: movlt [[LOW:r[0-9]+]], r0
; ARM32: cmp [[R]], #0
; ARM32: movlt [[HIGH:r[0-9]+]], r1
; ARM32: movne
; ARM32: mov r0, [[LOW]]
; ARM32: movne
; ARM32: mov r1, [[HIGH]]
; ARM32-DAG: mov r0
; ARM32-DAG: mov r1
; ARM32: bx lr
; ARM32: bx lr
...
@@ -168,12 +169,10 @@ entry:
...
@@ -168,12 +169,10 @@ entry:
; CHECK: cmovl
; CHECK: cmovl
; ARM32-LABEL: fold_cmp_select_64_undef
; ARM32-LABEL: fold_cmp_select_64_undef
; ARM32: cmp {{r[0-9]+}}, r0
; ARM32: cmp {{r[0-9]+}}, r0
; ARM32: movlt [[R:r[0-9]+]], #1
; ARM32: movge
; ARM32: cmp [[R]]
; ARM32: movlt
; ARM32: movne
; ARM32: movge
; ARM32: movne
; ARM32: movlt
; ARM32-DAG: mov r0
; ARM32-DAG: mov r1
; ARM32: bx lr
; ARM32: bx lr
...
@@ -192,17 +191,10 @@ entry:
...
@@ -192,17 +191,10 @@ entry:
; CHECK: cmp
; CHECK: cmp
; CHECK: cmovl
; CHECK: cmovl
; ARM32-LABEL: fold_cmp_select_intervening_insts
; ARM32-LABEL: fold_cmp_select_intervening_insts
; ARM32: mov [[RES0:r[4-7]+]], r0
; ARM32: mov [[RES1:r[4-7]+]], r1
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: cmp r{{[0-9]+}}, r{{[0-9]+}}
; ARM32: movlt [[R]], #1
; ARM32: mov [[R2:r[4-7]]], [[R]]
; ARM32: bl use_value
; ARM32: bl use_value
; ARM32: cmp [[R2]], #0
; ARM32: cmp r{{[0-9]+}}, r{{[0-9]+}}
; ARM32: movne [[RES1]], [[RES0]]
; ARM32: movlt
; ARM32: mov r0, [[RES1]]
; ARM32: bx lr
; Cmp/multi-select folding.
; Cmp/multi-select folding.
define
internal
i32
@fold_cmp_select_multi
(
i32
%arg1
,
i32
%arg2
)
{
define
internal
i32
@fold_cmp_select_multi
(
i32
%arg1
,
i32
%arg2
)
{
...
@@ -226,20 +218,14 @@ entry:
...
@@ -226,20 +218,14 @@ entry:
; CHECK: add
; CHECK: add
; CHECK: add
; CHECK: add
; ARM32-LABEL: fold_cmp_select_multi
; ARM32-LABEL: fold_cmp_select_multi
; ARM32: mov [[T0:r[0-9]+]], #0
; ARM32: cmp r0, r1
; ARM32: cmp r0, r1
; ARM32: movlt [[T0]], #1
; ARM32: movlt {{r[0-9]+}}, r0
; ARM32: uxtb [[T1:r[0-9]+]], [[T1]]
; ARM32: cmp r0, r1
; ARM32-NEXT: cmp [[T1]], #0
; ARM32: movlt {{r[0-9]+}}, r1
; ARM32: movne [[T2:r[0-9]+]], r0
; ARM32: cmp r0, r1
; ARM32: uxtb [[T3:r[0-9]+]], [[T3]]
; ARM32: movlt {{r[0-9]+}}, #123
; ARM32-NEXT: cmp [[T3]], #0
; ARM32: add
; ARM32: movne [[T4:r[0-9]+]], r1
; ARM32: add
; ARM32: uxtb [[T5:r[0-9]+]], [[T5]]
; ARM32-NEXT: cmp [[T5]], #0
; ARM32: movne [[T6:r[0-9]+]], #123
; ARM32: add [[T7:r[0-9]+]], [[T2]], [[T4]]
; ARM32: add {{r[0-9]+}}, [[T7]], [[T6]]
; ARM32: bx lr
; ARM32: bx lr
...
@@ -269,21 +255,21 @@ next:
...
@@ -269,21 +255,21 @@ next:
; CHECK: add
; CHECK: add
; ARM32-LABEL: no_fold_cmp_select_multi_liveout
; ARM32-LABEL: no_fold_cmp_select_multi_liveout
; ARM32-LABEL: fold_cmp_select_multi
; ARM32-LABEL: fold_cmp_select_multi
; ARM32: mov [[T0:r[0-9]+]], #0
; ARM32: cmp r0, r1
; ARM32: cmp r0, r1
; ARM32: movge [[T0:r[0-9]+]], #0
; ARM32: movlt [[T0]], #1
; ARM32: movlt [[T0]], #1
; ARM32: uxtb [[T
2:r[0-9]+]], [[T2
]]
; ARM32: uxtb [[T
1:r[0-9]+]], [[T1
]]
; ARM32-NEXT: cmp [[T
2
]], #0
; ARM32-NEXT: cmp [[T
1
]], #0
; ARM32: movne [[T
1
]], r0
; ARM32: movne [[T
2:r[0-9]+
]], r0
; ARM32: uxtb [[T
4:r[0-9]+]], [[T4
]]
; ARM32: uxtb [[T
3:r[0-9]+]], [[T3
]]
; ARM32-NEXT: cmp [[T
4
]], #0
; ARM32-NEXT: cmp [[T
3
]], #0
; ARM32: movne [[T
3
]], r1
; ARM32: movne [[T
4:r[0-9]+
]], r1
; ARM32-LABEL: .Lno_fold_cmp_select_multi_liveout$next:
; ARM32-LABEL: .Lno_fold_cmp_select_multi_liveout$next:
; ARM32: uxtb [[T5:r[0-9]+]], [[T5]]
; ARM32: uxtb [[T5:r[0-9]+]], [[T5]]
; ARM32: cmp [[T5]], #0
; ARM32: cmp [[T5]], #0
; ARM32: movne [[T6:r[0-9]+]], #123
; ARM32: movne [[T6:r[0-9]+]], #123
; ARM32: add
[[T7:r[0-9]+]], [[T2]], [[T4]]
; ARM32: add
; ARM32: add
{{r[0-9]+}}, [[T7]], [[T6]]
; ARM32: add
; ARM32: bx lr
; ARM32: bx lr
; Cmp/multi-select non-folding because of extra non-whitelisted uses.
; Cmp/multi-select non-folding because of extra non-whitelisted uses.
...
@@ -314,19 +300,19 @@ entry:
...
@@ -314,19 +300,19 @@ entry:
; CHECK: add
; CHECK: add
; CHECK: add
; CHECK: add
; ARM32-LABEL: no_fold_cmp_select_multi_non_whitelist
; ARM32-LABEL: no_fold_cmp_select_multi_non_whitelist
; ARM32: mov [[T0:r[0-9]+]], #0
; ARM32: cmp r0, r1
; ARM32: cmp r0, r1
; ARM32: movlt [[T0]], #1
; ARM32: movge [[R0:r[0-9]+]]
; ARM32: uxtb [[T1:r[0-9]+]], [[T1]]
; ARM32: movlt [[R0]]
; ARM32-NEXT: cmp [[T1]], #0
; ARM32: cmp r0, r1
; ARM32: movne [[T2:r[0-9]+]], r0
; ARM32: movge [[R1:r[0-9]+]]
; ARM32: uxtb [[T3:r[0-9]+]], [[T3]]
; ARM32: movlt [[R1]]
; ARM32-NEXT: cmp [[T3]], #0
; ARM32: cmp r0, r1
; ARM32: movne [[T4:r[0-9]+]], r1
; ARM32: movge [[R2:r[0-9]+]]
; ARM32: uxtb [[T5:r[0-9]+]], [[T5]]
; ARM32: movlt [[R2]]
; ARM32-NEXT: cmp [[T5]], #0
; ARM32: cmp r0, r1
; ARM32: movne [[T6:r[0-9]+]], #123
; ARM32: movge [[R3:r[0-9]+]]
; ARM32: and [[T7:r[0-9]+]], [[T0]], #1
; ARM32: movlt [[R3]]
; ARM32: add [[T8:r[0-9]+]], [[T2]], [[T4]]
; ARM32: add
; ARM32: add {{r[0-9]+}}, [[T8]], [[T7]]
; ARM32: add
; ARM32: add
; ARM32: bx lr
; ARM32: bx lr
tests_lit/llvm2ice_tests/branch-opt.ll
View file @
4a5e6d05
...
@@ -14,14 +14,14 @@
...
@@ -14,14 +14,14 @@
; when possible.
; when possible.
; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --disassemble --target arm32 -i %s --args -O2
--skip-unimplemented
\
; RUN: --disassemble --target arm32 -i %s --args -O2 \
; RUN: -allow-externally-defined-symbols \
; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32O2 %s
; RUN: --command FileCheck --check-prefix ARM32O2 %s
; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --disassemble --target arm32 -i %s --args -Om1
--skip-unimplemented
\
; RUN: --disassemble --target arm32 -i %s --args -Om1 \
; RUN: -allow-externally-defined-symbols \
; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck \
; RUN: --command FileCheck \
...
@@ -95,10 +95,7 @@ target:
...
@@ -95,10 +95,7 @@ target:
; Note that compare and branch folding isn't implemented yet (unlike x86-32).
; Note that compare and branch folding isn't implemented yet (unlike x86-32).
; ARM32O2-LABEL: testCondFallthroughToNextBlock
; ARM32O2-LABEL: testCondFallthroughToNextBlock
; ARM32O2: cmp {{.*}}, #123
; ARM32O2: cmp {{.*}}, #123
; ARM32O2-NEXT: movge {{.*}}, #1
; ARM32O2-NEXT: bge
; ARM32O2-NEXT: uxtb
; ARM32O2-NEXT: cmp {{.*}}, #0
; ARM32O2-NEXT: bne
; ARM32O2-NEXT: bl
; ARM32O2-NEXT: bl
; ARM32O2: bx lr
; ARM32O2: bx lr
; ARM32O2: bl
; ARM32O2: bl
...
@@ -106,7 +103,8 @@ target:
...
@@ -106,7 +103,8 @@ target:
; ARM32OM1-LABEL: testCondFallthroughToNextBlock
; ARM32OM1-LABEL: testCondFallthroughToNextBlock
; ARM32OM1: cmp {{.*}}, #123
; ARM32OM1: cmp {{.*}}, #123
; ARM32OM1-NEXT: movge {{.*}}, #1
; ARM32OM1: movlt {{.*}}, #0
; ARM32OM1: movge {{.*}}, #1
; ARM32OM1: cmp {{.*}}, #0
; ARM32OM1: cmp {{.*}}, #0
; ARM32OM1: bne
; ARM32OM1: bne
; ARM32OM1: b
; ARM32OM1: b
...
@@ -154,10 +152,7 @@ target:
...
@@ -154,10 +152,7 @@ target:
; (compared to x86-32).
; (compared to x86-32).
; ARM32O2-LABEL: testCondTargetNextBlock
; ARM32O2-LABEL: testCondTargetNextBlock
; ARM32O2: cmp {{.*}}, #123
; ARM32O2: cmp {{.*}}, #123
; ARM32O2-NEXT: movge {{.*}}, #1
; ARM32O2-NEXT: blt
; ARM32O2-NEXT: uxtb
; ARM32O2-NEXT: cmp {{.*}}, #0
; ARM32O2-NEXT: beq
; ARM32O2-NEXT: bl
; ARM32O2-NEXT: bl
; ARM32O2: bx lr
; ARM32O2: bx lr
; ARM32O2: bl
; ARM32O2: bl
...
...
tests_lit/llvm2ice_tests/fp.cmp.ll
View file @
4a5e6d05
...
@@ -9,16 +9,16 @@
...
@@ -9,16 +9,16 @@
; RUN: -allow-externally-defined-symbols | FileCheck %s
; RUN: -allow-externally-defined-symbols | FileCheck %s
; RUN: %if --need=allow_dump --need=target_ARM32 --command %p2i --filetype=asm \
; RUN: %if --need=allow_dump --need=target_ARM32 --command %p2i --filetype=asm \
; RUN: --target arm32 -i %s --args -O2
--skip-unimplemented
\
; RUN: --target arm32 -i %s --args -O2 \
; RUN: -allow-externally-defined-symbols \
; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=allow_dump --need=target_ARM32 --command FileCheck %s \
; RUN: | %if --need=allow_dump --need=target_ARM32 --command FileCheck %s \
; RUN: --check-prefix=ARM32
; RUN: --check-prefix=ARM32
--check-prefix=ARM32-O2
; RUN: %if --need=allow_dump --need=target_ARM32 --command %p2i --filetype=asm \
; RUN: %if --need=allow_dump --need=target_ARM32 --command %p2i --filetype=asm \
; RUN: --target arm32 -i %s --args -Om1
--skip-unimplemented
\
; RUN: --target arm32 -i %s --args -Om1 \
; RUN: -allow-externally-defined-symbols \
; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=allow_dump --need=target_ARM32 --command FileCheck %s \
; RUN: | %if --need=allow_dump --need=target_ARM32 --command FileCheck %s \
; RUN: --check-prefix=ARM32
; RUN: --check-prefix=ARM32
--check-prefix=ARM32-OM1
define
internal
void
@fcmpEq
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
define
internal
void
@fcmpEq
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
entry:
entry:
...
@@ -51,13 +51,16 @@ if.end3: ; preds = %if.then2, %if.end
...
@@ -51,13 +51,16 @@ if.end3: ; preds = %if.then2, %if.end
; CHECK: call {{.*}} R_{{.*}} func
; CHECK: call {{.*}} R_{{.*}} func
; ARM32-LABEL: fcmpEq
; ARM32-LABEL: fcmpEq
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R0:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: moveq [[R0]], #1
; ARM32-OM1: movne [[R0:r[0-9]+]], #0
; ARM32-OM1: moveq [[R0]], #1
; ARM32-O2: bne
; ARM32: bl func
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R1:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: moveq [[R1]], #1
; ARM32-OM1: movne [[R1:r[0-9]+]], #0
; ARM32-OM1: moveq [[R1]], #1
; ARM32-O2: bne
declare
void
@func
()
declare
void
@func
()
...
@@ -92,13 +95,15 @@ if.end3: ; preds = %if.then2, %if.end
...
@@ -92,13 +95,15 @@ if.end3: ; preds = %if.then2, %if.end
; CHECK: call {{.*}} R_{{.*}} func
; CHECK: call {{.*}} R_{{.*}} func
; ARM32-LABEL: fcmpNe
; ARM32-LABEL: fcmpNe
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R0:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movne [[R0]], #1
; ARM32-OM1: moveq [[R0:r[0-9]+]], #0
; ARM32-OM1: movne [[R0]], #1
; ARM32-O2: beq
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R1:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movne [[R1]], #1
; ARM32-OM1: moveq [[R1:r[0-9]+]], #0
; ARM32-OM1: movne [[R1]], #1
; ARM32-O2: beq
define
internal
void
@fcmpGt
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
define
internal
void
@fcmpGt
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
entry:
entry:
...
@@ -129,13 +134,15 @@ if.end3: ; preds = %if.then2, %if.end
...
@@ -129,13 +134,15 @@ if.end3: ; preds = %if.then2, %if.end
; CHECK: call {{.*}} R_{{.*}} func
; CHECK: call {{.*}} R_{{.*}} func
; ARM32-LABEL: fcmpGt
; ARM32-LABEL: fcmpGt
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R0:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movgt [[R0]], #1
; ARM32-OM1: movle [[R0:r[0-9]+]], #0
; ARM32-OM1: movgt [[R0]], #1
; ARM32-O2: ble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R1:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movgt [[R1]], #1
; ARM32-OM1: movle [[R1:r[0-9]+]], #0
; ARM32-OM1: movgt [[R1]], #1
; ARM32-O2: ble
define
internal
void
@fcmpGe
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
define
internal
void
@fcmpGe
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
entry:
entry:
...
@@ -166,13 +173,15 @@ if.end3: ; preds = %if.end, %if.then2
...
@@ -166,13 +173,15 @@ if.end3: ; preds = %if.end, %if.then2
; CHECK: call {{.*}} R_{{.*}} func
; CHECK: call {{.*}} R_{{.*}} func
; ARM32-LABEL: fcmpGe
; ARM32-LABEL: fcmpGe
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R0:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movlt [[R0]], #1
; ARM32-OM1: movge [[R0:r[0-9]+]], #0
; ARM32-OM1: movlt [[R0]], #1
; ARM32-O2: blt
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R1:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movlt [[R1]], #1
; ARM32-OM1: movge [[R1:r[0-9]+]], #0
; ARM32-OM1: movlt [[R1]], #1
; ARM32-O2: blt
define
internal
void
@fcmpLt
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
define
internal
void
@fcmpLt
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
entry:
entry:
...
@@ -203,13 +212,15 @@ if.end3: ; preds = %if.then2, %if.end
...
@@ -203,13 +212,15 @@ if.end3: ; preds = %if.then2, %if.end
; CHECK: call {{.*}} R_{{.*}} func
; CHECK: call {{.*}} R_{{.*}} func
; ARM32-LABEL: fcmpLt
; ARM32-LABEL: fcmpLt
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R0:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movmi [[R0]], #1
; ARM32-OM1: movpl [[R0:r[0-9]+]], #0
; ARM32-OM1: movmi [[R0]], #1
; ARM32-O2: bpl
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R1:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movmi [[R1]], #1
; ARM32-OM1: movpl [[R1:r[0-9]+]], #0
; ARM32-OM1: movmi [[R1]], #1
; ARM32-O2: bpl
define
internal
void
@fcmpLe
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
define
internal
void
@fcmpLe
(
float
%a
,
float
%b
,
double
%c
,
double
%d
)
{
entry:
entry:
...
@@ -240,13 +251,15 @@ if.end3: ; preds = %if.end, %if.then2
...
@@ -240,13 +251,15 @@ if.end3: ; preds = %if.end, %if.then2
; CHECK: call {{.*}} R_{{.*}} func
; CHECK: call {{.*}} R_{{.*}} func
; ARM32-LABEL: fcmpLe
; ARM32-LABEL: fcmpLe
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R0:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movhi [[R0]], #1
; ARM32-OM1: movls [[R0:r[0-9]+]], #0
; ARM32-OM1: movhi [[R0]], #1
; ARM32-O2: bhi
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R1:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movhi [[R1]], #1
; ARM32-OM1: movls [[R1:r[0-9]+]], #0
; ARM32-OM1: movhi [[R1]], #1
; ARM32-O2: bhi
define
internal
i32
@fcmpFalseFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpFalseFloat
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -257,7 +270,6 @@ entry:
...
@@ -257,7 +270,6 @@ entry:
; CHECK-LABEL: fcmpFalseFloat
; CHECK-LABEL: fcmpFalseFloat
; CHECK: mov {{.*}},0x0
; CHECK: mov {{.*}},0x0
; ARM32-LABEL: fcmpFalseFloat
; ARM32-LABEL: fcmpFalseFloat
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: mov [[R:r[0-9]+]], #0
define
internal
i32
@fcmpFalseDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpFalseDouble
(
double
%a
,
double
%b
)
{
...
@@ -269,7 +281,6 @@ entry:
...
@@ -269,7 +281,6 @@ entry:
; CHECK-LABEL: fcmpFalseDouble
; CHECK-LABEL: fcmpFalseDouble
; CHECK: mov {{.*}},0x0
; CHECK: mov {{.*}},0x0
; ARM32-LABEL: fcmpFalseDouble
; ARM32-LABEL: fcmpFalseDouble
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: mov [[R:r[0-9]+]], #0
define
internal
i32
@fcmpOeqFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpOeqFloat
(
float
%a
,
float
%b
)
{
...
@@ -284,8 +295,8 @@ entry:
...
@@ -284,8 +295,8 @@ entry:
; CHECK: jp
; CHECK: jp
; ARM32-LABEL: fcmpOeqFloat
; ARM32-LABEL: fcmpOeqFloat
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movne [[R:r[0-9]+]], #0
; ARM32: moveq [[R]], #1
; ARM32: moveq [[R]], #1
define
internal
i32
@fcmpOeqDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpOeqDouble
(
double
%a
,
double
%b
)
{
...
@@ -300,8 +311,8 @@ entry:
...
@@ -300,8 +311,8 @@ entry:
; CHECK: jp
; CHECK: jp
; ARM32-LABEL: fcmpOeqDouble
; ARM32-LABEL: fcmpOeqDouble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movne [[R:r[0-9]+]], #0
; ARM32: moveq [[R]], #1
; ARM32: moveq [[R]], #1
define
internal
i32
@fcmpOgtFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpOgtFloat
(
float
%a
,
float
%b
)
{
...
@@ -315,8 +326,8 @@ entry:
...
@@ -315,8 +326,8 @@ entry:
; CHECK: seta
; CHECK: seta
; ARM32-LABEL: fcmpOgtFloat
; ARM32-LABEL: fcmpOgtFloat
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movle [[R:r[0-9]+]], #0
; ARM32: movgt [[R]], #1
; ARM32: movgt [[R]], #1
define
internal
i32
@fcmpOgtDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpOgtDouble
(
double
%a
,
double
%b
)
{
...
@@ -330,8 +341,8 @@ entry:
...
@@ -330,8 +341,8 @@ entry:
; CHECK: seta
; CHECK: seta
; ARM32-LABEL: fcmpOgtDouble
; ARM32-LABEL: fcmpOgtDouble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movle [[R:r[0-9]+]], #0
; ARM32: movgt [[R]], #1
; ARM32: movgt [[R]], #1
define
internal
i32
@fcmpOgeFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpOgeFloat
(
float
%a
,
float
%b
)
{
...
@@ -345,8 +356,8 @@ entry:
...
@@ -345,8 +356,8 @@ entry:
; CHECK: setae
; CHECK: setae
; ARM32-LABEL: fcmpOgeFloat
; ARM32-LABEL: fcmpOgeFloat
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movlt [[R:r[0-9]+]], #0
; ARM32: movge [[R]], #1
; ARM32: movge [[R]], #1
define
internal
i32
@fcmpOgeDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpOgeDouble
(
double
%a
,
double
%b
)
{
...
@@ -360,8 +371,8 @@ entry:
...
@@ -360,8 +371,8 @@ entry:
; CHECK: setae
; CHECK: setae
; ARM32-LABEL: fcmpOgeDouble
; ARM32-LABEL: fcmpOgeDouble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movlt [[R:r[0-9]+]], #0
; ARM32: movge [[R]], #1
; ARM32: movge [[R]], #1
define
internal
i32
@fcmpOltFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpOltFloat
(
float
%a
,
float
%b
)
{
...
@@ -375,8 +386,8 @@ entry:
...
@@ -375,8 +386,8 @@ entry:
; CHECK: seta
; CHECK: seta
; ARM32-LABEL: fcmpOltFloat
; ARM32-LABEL: fcmpOltFloat
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movpl [[R:r[0-9]+]], #0
; ARM32: movmi [[R]], #1
; ARM32: movmi [[R]], #1
define
internal
i32
@fcmpOltDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpOltDouble
(
double
%a
,
double
%b
)
{
...
@@ -390,8 +401,8 @@ entry:
...
@@ -390,8 +401,8 @@ entry:
; CHECK: seta
; CHECK: seta
; ARM32-LABEL: fcmpOltDouble
; ARM32-LABEL: fcmpOltDouble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movpl [[R:r[0-9]+]], #0
; ARM32: movmi [[R]], #1
; ARM32: movmi [[R]], #1
define
internal
i32
@fcmpOleFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpOleFloat
(
float
%a
,
float
%b
)
{
...
@@ -405,8 +416,8 @@ entry:
...
@@ -405,8 +416,8 @@ entry:
; CHECK: setae
; CHECK: setae
; ARM32-LABEL: fcmpOleFloat
; ARM32-LABEL: fcmpOleFloat
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movhi [[R:r[0-9]+]], #0
; ARM32: movls [[R]], #1
; ARM32: movls [[R]], #1
define
internal
i32
@fcmpOleDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpOleDouble
(
double
%a
,
double
%b
)
{
...
@@ -420,8 +431,8 @@ entry:
...
@@ -420,8 +431,8 @@ entry:
; CHECK: setae
; CHECK: setae
; ARM32-LABEL: fcmpOleDouble
; ARM32-LABEL: fcmpOleDouble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movhi [[R:r[0-9]+]], #0
; ARM32: movls [[R]], #1
; ARM32: movls [[R]], #1
define
internal
i32
@fcmpOneFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpOneFloat
(
float
%a
,
float
%b
)
{
...
@@ -435,8 +446,8 @@ entry:
...
@@ -435,8 +446,8 @@ entry:
; CHECK: setne
; CHECK: setne
; ARM32-LABEL: fcmpOneFloat
; ARM32-LABEL: fcmpOneFloat
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: movmi [[R]], #1
; ARM32: movmi [[R]], #1
; ARM32: movgt [[R]], #1
; ARM32: movgt [[R]], #1
...
@@ -451,8 +462,8 @@ entry:
...
@@ -451,8 +462,8 @@ entry:
; CHECK: setne
; CHECK: setne
; ARM32-LABEL: fcmpOneDouble
; ARM32-LABEL: fcmpOneDouble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: movmi [[R]], #1
; ARM32: movmi [[R]], #1
; ARM32: movgt [[R]], #1
; ARM32: movgt [[R]], #1
...
@@ -467,8 +478,8 @@ entry:
...
@@ -467,8 +478,8 @@ entry:
; CHECK: setnp
; CHECK: setnp
; ARM32-LABEL: fcmpOrdFloat
; ARM32-LABEL: fcmpOrdFloat
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movvs [[R:r[0-9]+]], #0
; ARM32: movvc [[R]], #1
; ARM32: movvc [[R]], #1
define
internal
i32
@fcmpOrdDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpOrdDouble
(
double
%a
,
double
%b
)
{
...
@@ -482,8 +493,8 @@ entry:
...
@@ -482,8 +493,8 @@ entry:
; CHECK: setnp
; CHECK: setnp
; ARM32-LABEL: fcmpOrdDouble
; ARM32-LABEL: fcmpOrdDouble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movvs [[R:r[0-9]+]], #0
; ARM32: movvc [[R]], #1
; ARM32: movvc [[R]], #1
define
internal
i32
@fcmpUeqFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpUeqFloat
(
float
%a
,
float
%b
)
{
...
@@ -497,8 +508,8 @@ entry:
...
@@ -497,8 +508,8 @@ entry:
; CHECK: sete
; CHECK: sete
; ARM32-LABEL: fcmpUeqFloat
; ARM32-LABEL: fcmpUeqFloat
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: moveq [[R]], #1
; ARM32: moveq [[R]], #1
; ARM32: movvs [[R]], #1
; ARM32: movvs [[R]], #1
...
@@ -513,8 +524,8 @@ entry:
...
@@ -513,8 +524,8 @@ entry:
; CHECK: sete
; CHECK: sete
; ARM32-LABEL: fcmpUeqDouble
; ARM32-LABEL: fcmpUeqDouble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: moveq [[R]], #1
; ARM32: moveq [[R]], #1
; ARM32: movvs [[R]], #1
; ARM32: movvs [[R]], #1
...
@@ -529,8 +540,8 @@ entry:
...
@@ -529,8 +540,8 @@ entry:
; CHECK: setb
; CHECK: setb
; ARM32-LABEL: fcmpUgtFloat
; ARM32-LABEL: fcmpUgtFloat
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movls [[R:r[0-9]+]], #0
; ARM32: movhi [[R]], #1
; ARM32: movhi [[R]], #1
define
internal
i32
@fcmpUgtDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpUgtDouble
(
double
%a
,
double
%b
)
{
...
@@ -544,8 +555,8 @@ entry:
...
@@ -544,8 +555,8 @@ entry:
; CHECK: setb
; CHECK: setb
; ARM32-LABEL: fcmpUgtDouble
; ARM32-LABEL: fcmpUgtDouble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movls [[R:r[0-9]+]], #0
; ARM32: movhi [[R]], #1
; ARM32: movhi [[R]], #1
define
internal
i32
@fcmpUgeFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpUgeFloat
(
float
%a
,
float
%b
)
{
...
@@ -559,8 +570,8 @@ entry:
...
@@ -559,8 +570,8 @@ entry:
; CHECK: setbe
; CHECK: setbe
; ARM32-LABEL: fcmpUgeFloat
; ARM32-LABEL: fcmpUgeFloat
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movmi [[R:r[0-9]+]], #0
; ARM32: movpl [[R]], #1
; ARM32: movpl [[R]], #1
define
internal
i32
@fcmpUgeDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpUgeDouble
(
double
%a
,
double
%b
)
{
...
@@ -574,8 +585,8 @@ entry:
...
@@ -574,8 +585,8 @@ entry:
; CHECK: setbe
; CHECK: setbe
; ARM32-LABEL: fcmpUgeDouble
; ARM32-LABEL: fcmpUgeDouble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movmi [[R:r[0-9]+]], #0
; ARM32: movpl [[R]], #1
; ARM32: movpl [[R]], #1
define
internal
i32
@fcmpUltFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpUltFloat
(
float
%a
,
float
%b
)
{
...
@@ -589,8 +600,8 @@ entry:
...
@@ -589,8 +600,8 @@ entry:
; CHECK: setb
; CHECK: setb
; ARM32-LABEL: fcmpUltFloat
; ARM32-LABEL: fcmpUltFloat
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movge [[R:r[0-9]+]], #0
; ARM32: movlt [[R]], #1
; ARM32: movlt [[R]], #1
define
internal
i32
@fcmpUltDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpUltDouble
(
double
%a
,
double
%b
)
{
...
@@ -604,8 +615,8 @@ entry:
...
@@ -604,8 +615,8 @@ entry:
; CHECK: setb
; CHECK: setb
; ARM32-LABEL: fcmpUltDouble
; ARM32-LABEL: fcmpUltDouble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movge [[R:r[0-9]+]], #0
; ARM32: movlt [[R]], #1
; ARM32: movlt [[R]], #1
define
internal
i32
@fcmpUleFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpUleFloat
(
float
%a
,
float
%b
)
{
...
@@ -619,8 +630,8 @@ entry:
...
@@ -619,8 +630,8 @@ entry:
; CHECK: setbe
; CHECK: setbe
; ARM32-LABEL: fcmpUleFloat
; ARM32-LABEL: fcmpUleFloat
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movgt [[R:r[0-9]+]], #0
; ARM32: movle [[R]], #1
; ARM32: movle [[R]], #1
define
internal
i32
@fcmpUleDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpUleDouble
(
double
%a
,
double
%b
)
{
...
@@ -634,8 +645,8 @@ entry:
...
@@ -634,8 +645,8 @@ entry:
; CHECK: setbe
; CHECK: setbe
; ARM32-LABEL: fcmpUleDouble
; ARM32-LABEL: fcmpUleDouble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movgt [[R:r[0-9]+]], #0
; ARM32: movle [[R]], #1
; ARM32: movle [[R]], #1
define
internal
i32
@fcmpUneFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpUneFloat
(
float
%a
,
float
%b
)
{
...
@@ -650,8 +661,8 @@ entry:
...
@@ -650,8 +661,8 @@ entry:
; CHECK: jp
; CHECK: jp
; ARM32-LABEL: fcmpUneFloat
; ARM32-LABEL: fcmpUneFloat
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: moveq [[R:r[0-9]+]], #0
; ARM32: movne [[R]], #1
; ARM32: movne [[R]], #1
define
internal
i32
@fcmpUneDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpUneDouble
(
double
%a
,
double
%b
)
{
...
@@ -666,8 +677,8 @@ entry:
...
@@ -666,8 +677,8 @@ entry:
; CHECK: jp
; CHECK: jp
; ARM32-LABEL: fcmpUneDouble
; ARM32-LABEL: fcmpUneDouble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: moveq [[R:r[0-9]+]], #0
; ARM32: movne [[R]], #1
; ARM32: movne [[R]], #1
define
internal
i32
@fcmpUnoFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpUnoFloat
(
float
%a
,
float
%b
)
{
...
@@ -681,8 +692,8 @@ entry:
...
@@ -681,8 +692,8 @@ entry:
; CHECK: setp
; CHECK: setp
; ARM32-LABEL: fcmpUnoFloat
; ARM32-LABEL: fcmpUnoFloat
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movvc [[R:r[0-9]+]], #0
; ARM32: movvs [[R]], #1
; ARM32: movvs [[R]], #1
define
internal
i32
@fcmpUnoDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpUnoDouble
(
double
%a
,
double
%b
)
{
...
@@ -696,8 +707,8 @@ entry:
...
@@ -696,8 +707,8 @@ entry:
; CHECK: setp
; CHECK: setp
; ARM32-LABEL: fcmpUnoDouble
; ARM32-LABEL: fcmpUnoDouble
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: mov [[R:r[0-9]+]], #0
; ARM32: vmrs
; ARM32: vmrs
; ARM32: movvc [[R:r[0-9]+]], #0
; ARM32: movvs [[R]], #1
; ARM32: movvs [[R]], #1
define
internal
i32
@fcmpTrueFloat
(
float
%a
,
float
%b
)
{
define
internal
i32
@fcmpTrueFloat
(
float
%a
,
float
%b
)
{
...
@@ -709,8 +720,7 @@ entry:
...
@@ -709,8 +720,7 @@ entry:
; CHECK-LABEL: fcmpTrueFloat
; CHECK-LABEL: fcmpTrueFloat
; CHECK: mov {{.*}},0x1
; CHECK: mov {{.*}},0x1
; ARM32-LABEL: fcmpTrueFloat
; ARM32-LABEL: fcmpTrueFloat
; ARM32: vcmp.f32
; ARM32: mov {{r[0-9]+}}, #1
; ARM32: mov [[R]], #1
define
internal
i32
@fcmpTrueDouble
(
double
%a
,
double
%b
)
{
define
internal
i32
@fcmpTrueDouble
(
double
%a
,
double
%b
)
{
entry:
entry:
...
@@ -721,8 +731,7 @@ entry:
...
@@ -721,8 +731,7 @@ entry:
; CHECK-LABEL: fcmpTrueDouble
; CHECK-LABEL: fcmpTrueDouble
; CHECK: mov {{.*}},0x1
; CHECK: mov {{.*}},0x1
; ARM32-LABEL: fcmpTrueDouble
; ARM32-LABEL: fcmpTrueDouble
; ARM32: vcmp.f64
; ARM32: mov {{r[0-9]+}}, #1
; ARM32: mov [[R]], #1
define
internal
float
@selectFloatVarVar
(
float
%a
,
float
%b
)
{
define
internal
float
@selectFloatVarVar
(
float
%a
,
float
%b
)
{
entry:
entry:
...
@@ -736,7 +745,8 @@ entry:
...
@@ -736,7 +745,8 @@ entry:
; CHECK: fld
; CHECK: fld
; ARM32-LABEL: selectFloatVarVar
; ARM32-LABEL: selectFloatVarVar
; ARM32: vcmp.f32
; ARM32: vcmp.f32
; ARM32: vmovne.f32 s{{[0-9]+}}
; ARM32-OM1: vmovne.f32 s{{[0-9]+}}
; ARM32-O2: vmovmi.f32 s{{[0-9]+}}
; ARM32: bx
; ARM32: bx
define
internal
double
@selectDoubleVarVar
(
double
%a
,
double
%b
)
{
define
internal
double
@selectDoubleVarVar
(
double
%a
,
double
%b
)
{
...
@@ -751,5 +761,6 @@ entry:
...
@@ -751,5 +761,6 @@ entry:
; CHECK: fld
; CHECK: fld
; ARM32-LABEL: selectDoubleVarVar
; ARM32-LABEL: selectDoubleVarVar
; ARM32: vcmp.f64
; ARM32: vcmp.f64
; ARM32: vmovne.f64 d{{[0-9]+}}
; ARM32-OM1: vmovne.f64 d{{[0-9]+}}
; ARM32-O2: vmovmi.f64 d{{[0-9]+}}
; ARM32: bx
; ARM32: bx
tests_lit/llvm2ice_tests/select-opt.ll
View file @
4a5e6d05
...
@@ -12,16 +12,16 @@
...
@@ -12,16 +12,16 @@
; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --disassemble --target arm32 -i %s --args -O2
--skip-unimplemented
\
; RUN: --disassemble --target arm32 -i %s --args -O2 \
; RUN: -allow-externally-defined-symbols \
; RUN: -allow-externally-defined-symbols \
; 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-O2
%s
; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --disassemble --target arm32 -i %s --args -Om1
--skip-unimplemented
\
; RUN: --disassemble --target arm32 -i %s --args -Om1 \
; RUN: -allow-externally-defined-symbols \
; RUN: -allow-externally-defined-symbols \
; 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-OM1
%s
define
internal
void
@testSelect
(
i32
%a
,
i32
%b
)
{
define
internal
void
@testSelect
(
i32
%a
,
i32
%b
)
{
entry:
entry:
...
@@ -51,12 +51,16 @@ declare void @useInt(i32 %x)
...
@@ -51,12 +51,16 @@ declare void @useInt(i32 %x)
; CHECK: ret
; CHECK: ret
; ARM32-LABEL: testSelect
; ARM32-LABEL: testSelect
; ARM32: cmp
; ARM32: cmp
; ARM32: cmp
; ARM32
-OM1
: cmp
; ARM32: bl {{.*}} useInt
; ARM32: bl {{.*}} useInt
; ARM32: cmp
; ARM32: cmp
; ARM32: cmp
; ARM32-Om1: cmp
; ARM32: mov {{.*}}, #20
; ARM32-Om1: mov {{.*}}, #20
; ARM32: movne {{.*}}, #10
; ARM32-Om1: movne {{.*}}, #10
; ARM32-O2: movle [[REG:r[0-9]+]], #20
; ARM32-O2: movgt [[REG]], #10
; ARM32: bl {{.*}} useInt
; ARM32: bl {{.*}} useInt
; ARM32: bl {{.*}} useInt
; ARM32: bl {{.*}} useInt
; ARM32: bx lr
; ARM32: bx lr
...
...
tests_lit/llvm2ice_tests/test_i1.ll
View file @
4a5e6d05
...
@@ -8,17 +8,10 @@
...
@@ -8,17 +8,10 @@
; RUN: --target x8632 -i %s --args -Om1 \
; RUN: --target x8632 -i %s --args -Om1 \
; RUN: | %if --need=target_X8632 --command FileCheck %s
; RUN: | %if --need=target_X8632 --command FileCheck %s
; TODO(jvoung): Stop skipping unimplemented parts (via --skip-unimplemented)
; TODO(jpp): Switch to --filetype=obj when possible.
; once enough infrastructure is in. Also, switch to --filetype=obj
; when possible.
; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --disassemble --target arm32 -i %s --args -O2 --skip-unimplemented \
; RUN: --disassemble --target arm32 -i %s --args -O2 \
; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 %s
; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --disassemble --target arm32 -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 %s
...
@@ -73,7 +66,9 @@ entry:
...
@@ -73,7 +66,9 @@ entry:
; CHECK-LABEL: testTrunc
; CHECK-LABEL: testTrunc
; CHECK: and {{.*}},0x1
; CHECK: and {{.*}},0x1
; ARM32-LABEL: testTrunc
; ARM32-LABEL: testTrunc
; ARM32: and {{.*}}, #1
; ARM32: tst r0, #1
; ARM32: moveq [[REG:r[0-9]*]], #0
; ARM32: movne [[REG]], #1
; Test zext to i8.
; Test zext to i8.
define
internal
i32
@testZextI8
(
i32
%arg
)
{
define
internal
i32
@testZextI8
(
i32
%arg
)
{
...
@@ -89,8 +84,10 @@ entry:
...
@@ -89,8 +84,10 @@ entry:
; match the zext i1 instruction (NOTE: no mov need between i1 and i8).
; match the zext i1 instruction (NOTE: no mov need between i1 and i8).
; CHECK-NOT: and {{.*}},0x1
; CHECK-NOT: and {{.*}},0x1
; ARM32-LABEL: testZextI8
; ARM32-LABEL: testZextI8
; ARM32: and {{.*}}, #1
; ARM32: tst r0, #1
; ARM32: and {{.*}}, #1
; ARM32: moveq [[REG:r[0-9]*]], #0
; ARM32: movne [[REG]], #1
; ARM32: uxtb [[REG]]
; Test zext to i16.
; Test zext to i16.
define
internal
i32
@testZextI16
(
i32
%arg
)
{
define
internal
i32
@testZextI16
(
i32
%arg
)
{
...
@@ -108,10 +105,10 @@ entry:
...
@@ -108,10 +105,10 @@ entry:
; CHECK-NOT: and [[REG]],0x1
; CHECK-NOT: and [[REG]],0x1
; ARM32-LABEL: testZextI16
; ARM32-LABEL: testZextI16
;
match the trunc instruction
;
ARM32: tst r0, #1
; ARM32:
and {{.*}}, #1
; ARM32:
moveq [[REG:r[0-9]*]], #0
;
match the zext (no need to uxt into a reg if src is already in a reg)
;
ARM32: movne [[REG]], #1
; ARM32:
and {{.*}}, #1
; ARM32:
uxth [[REG]]
; Test zext to i32.
; Test zext to i32.
define
internal
i32
@testZextI32
(
i32
%arg
)
{
define
internal
i32
@testZextI32
(
i32
%arg
)
{
...
@@ -127,8 +124,9 @@ entry:
...
@@ -127,8 +124,9 @@ entry:
; CHECK: movzx
; CHECK: movzx
; CHECK-NOT: and {{.*}},0x1
; CHECK-NOT: and {{.*}},0x1
; ARM32-LABEL: testZextI32
; ARM32-LABEL: testZextI32
; ARM32: and {{.*}}, #1
; ARM32: tst r0, #1
; ARM32: and {{.*}}, #1
; ARM32: moveq [[REG:r[0-9]*]], #0
; ARM32: movne [[REG]], #1
; Test zext to i64.
; Test zext to i64.
define
internal
i64
@testZextI64
(
i32
%arg
)
{
define
internal
i64
@testZextI64
(
i32
%arg
)
{
...
@@ -144,9 +142,10 @@ entry:
...
@@ -144,9 +142,10 @@ entry:
; CHECK: movzx
; CHECK: movzx
; CHECK: mov {{.*}},0x0
; CHECK: mov {{.*}},0x0
; ARM32-LABEL: testZextI64
; ARM32-LABEL: testZextI64
; ARM32: and {{.*}}, #1
; ARM32: tst r0, #1
; ARM32: and {{.*}}, #1
; ARM32: mov r{{[0-9]*}}, #0
; ARM32: mov {{.*}}, #0
; ARM32: moveq [[REG:r[0-9]*]], #0
; ARM32: movne [[REG]], #1
; Test sext to i8.
; Test sext to i8.
define
internal
i32
@testSextI8
(
i32
%arg
)
{
define
internal
i32
@testSextI8
(
i32
%arg
)
{
...
@@ -163,13 +162,12 @@ entry:
...
@@ -163,13 +162,12 @@ entry:
; CHECK: shl [[REG:.*]],0x7
; CHECK: shl [[REG:.*]],0x7
; CHECK-NEXT: sar [[REG]],0x7
; CHECK-NEXT: sar [[REG]],0x7
;
;
; ARM shifts by 32, since there aren't any byte regs.
; ARM32-LABEL: testSextI8
; ARM32-LABEL: testSextI8
;
match the trunc instruction
;
ARM32: tst r0, #1
; ARM32:
and {{.*}}, #1
; ARM32:
mvn [[REG_M1:r[0-9]*]], #0
;
match the sext i1 instruction
;
ARM32: moveq [[REG:r[0-9]*]], #0
; ARM32:
lsl {{.*}}, #31
; ARM32:
movne [[REG]], [[REG_M1]]
; ARM32
-NEXT: asr {{.*}}, #31
; ARM32
: sxtb [[REG]]
; Test sext to i16.
; Test sext to i16.
define
internal
i32
@testSextI16
(
i32
%arg
)
{
define
internal
i32
@testSextI16
(
i32
%arg
)
{
...
@@ -188,9 +186,11 @@ entry:
...
@@ -188,9 +186,11 @@ entry:
; CHECK-NEXT: sar [[REG]],0xf
; CHECK-NEXT: sar [[REG]],0xf
; ARM32-LABEL: testSextI16
; ARM32-LABEL: testSextI16
; ARM32: and {{.*}}, #1
; ARM32: tst r0, #1
; ARM32: lsl {{.*}}, #31
; ARM32: mvn [[REG_M1:r[0-9]*]], #0
; ARM32-NEXT: asr {{.*}}, #31
; ARM32: moveq [[REG:r[0-9]*]], #0
; ARM32: movne [[REG]], [[REG_M1]]
; ARM32: sxth [[REG]]
; Test sext to i32.
; Test sext to i32.
define
internal
i32
@testSextI32
(
i32
%arg
)
{
define
internal
i32
@testSextI32
(
i32
%arg
)
{
...
@@ -208,9 +208,10 @@ entry:
...
@@ -208,9 +208,10 @@ entry:
; CHECK-NEXT: sar [[REG]],0x1f
; CHECK-NEXT: sar [[REG]],0x1f
; ARM32-LABEL: testSextI32
; ARM32-LABEL: testSextI32
; ARM32: and {{.*}}, #1
; ARM32: tst r0, #1
; ARM32: lsl {{.*}}, #31
; ARM32: mvn [[REG_M1:r[0-9]*]], #0
; ARM32-NEXT: asr {{.*}}, #31
; ARM32: moveq [[REG:r[0-9]*]], #0
; ARM32: movne [[REG]], [[REG_M1]]
; Test sext to i64.
; Test sext to i64.
define
internal
i64
@testSextI64
(
i32
%arg
)
{
define
internal
i64
@testSextI64
(
i32
%arg
)
{
...
@@ -228,10 +229,11 @@ entry:
...
@@ -228,10 +229,11 @@ entry:
; CHECK-NEXT: sar [[REG]],0x1f
; CHECK-NEXT: sar [[REG]],0x1f
; ARM32-LABEL: testSextI64
; ARM32-LABEL: testSextI64
; ARM32: and {{.*}}, #1
; ARM32: tst r0, #1
; ARM32: lsl {{.*}}, #31
; ARM32: mvn [[REG_M1:r[0-9]*]], #0
; ARM32-NEXT: asr [[REG:r.*]], {{.*}}, #31
; ARM32: moveq [[REG:r[0-9]*]], #0
; ARM32-NEXT: {{(mov|str).*}} [[REG]]
; ARM32: movne [[REG]], [[REG_M1]]
; ARM32: mov r{{[0-9]+}}, [[REG]]
; Kind of like sext i1 to i32, but with an immediate source. On ARM,
; Kind of like sext i1 to i32, but with an immediate source. On ARM,
; sxtb cannot take an immediate operand, so make sure it's using a reg.
; sxtb cannot take an immediate operand, so make sure it's using a reg.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment