Commit 7b3d9cbb by John Porto

Subzero. ARM32. New bool folding.

Improves the bool folding logic so that branches are short circuited. BUG= https://code.google.com/p/nativeclient/issues/detail?id=4076 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1417393003 .
parent f2674646
...@@ -882,7 +882,7 @@ void InstARM32Br::dump(const Cfg *Func) const { ...@@ -882,7 +882,7 @@ void InstARM32Br::dump(const Cfg *Func) const {
} }
if (Label) { if (Label) {
Str << "label %" << Label->getName(Func); Str << getPredicate() << ", label %" << Label->getName(Func);
} else { } else {
Str << getPredicate() << ", label %" << getTargetTrue()->getName(); Str << getPredicate() << ", label %" << getTargetTrue()->getName();
if (getTargetFalse()) { if (getTargetFalse()) {
......
...@@ -1136,6 +1136,7 @@ public: ...@@ -1136,6 +1136,7 @@ public:
} }
bool isRedundantAssign() const override { bool isRedundantAssign() const override {
return !isMultiDest() && !isMultiSource() && return !isMultiDest() && !isMultiSource() &&
getPredicate() == CondARM32::AL &&
checkForRedundantAssign(getDest(), getSrc(0)); checkForRedundantAssign(getDest(), getSrc(0));
} }
bool isVarAssign() const override { return llvm::isa<Variable>(getSrc(0)); } bool isVarAssign() const override { return llvm::isa<Variable>(getSrc(0)); }
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#ifndef SUBZERO_SRC_ICETLS_H #ifndef SUBZERO_SRC_ICETLS_H
#define SUBZERO_SRC_ICETLS_H #define SUBZERO_SRC_ICETLS_H
/// ///
/// @defgroup /IceTLS Defines 5 macros for unifying thread_local and pthread: /// @defgroup /IceTLS Defines 5 macros for unifying thread_local and pthread:
/// @{ /// @{
...@@ -96,7 +95,6 @@ ...@@ -96,7 +95,6 @@
#define ICE_ATTRIBUTE_TLS thread_local #define ICE_ATTRIBUTE_TLS thread_local
#endif // !_MSC_VER #endif // !_MSC_VER
#define ICE_TLS_DECLARE_FIELD(Type, FieldName) \ #define ICE_TLS_DECLARE_FIELD(Type, FieldName) \
static ICE_ATTRIBUTE_TLS Type FieldName static ICE_ATTRIBUTE_TLS Type FieldName
#define ICE_TLS_DEFINE_FIELD(Type, ClassName, FieldName) \ #define ICE_TLS_DEFINE_FIELD(Type, ClassName, FieldName) \
......
...@@ -82,7 +82,7 @@ public: ...@@ -82,7 +82,7 @@ public:
PK_Icmp64, PK_Icmp64,
PK_Fcmp, PK_Fcmp,
PK_Trunc, PK_Trunc,
PK_Arith // A flag-setting arithmetic instruction. PK_Arith // A flag-setting arithmetic instruction.
}; };
/// Currently the actual enum values are not used (other than CK_None), but we /// Currently the actual enum values are not used (other than CK_None), but we
......
...@@ -52,40 +52,40 @@ define internal void @mult_fwd_branches(i32 %a, i32 %b) { ...@@ -52,40 +52,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: mov r0, #0
; ASM-NEXT: ldr r1, [sp, #4] ; ASM-NEXT: ldr r1, [sp, #8]
; ASM-NEXT: cmp r0, r1 ; ASM-NEXT: ldr r2, [sp, #4]
; ASM-NEXT: movge r0, #0 ; ASM-NEXT: cmp r1, r2
; ASM-NEXT: movlt r0, #1 ; ASM-NEXT: movlt r0, #1
; ASM-NEXT: strb r0, [sp] ; ASM-NEXT: strb r0, [sp]
; DIS-NEXT: c: e59d0008 ; DIS-NEXT: c: e3a00000
; DIS-NEXT: 10: e59d1004 ; DIS-NEXT: 10: e59d1008
; DIS-NEXT: 14: e1500001 ; DIS-NEXT: 14: e59d2004
; DIS-NEXT: 18: a3a00000 ; DIS-NEXT: 18: e1510002
; DIS-NEXT: 1c: b3a00001 ; DIS-NEXT: 1c: b3a00001
; DIS-NEXT: 20: e5cd0000 ; DIS-NEXT: 20: e5cd0000
; IASM-NEXT: .byte 0x8
; IASM-NEXT: .byte 0x0 ; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0xa0
; IASM-NEXT: .byte 0xe3
; IASM-NEXT: .byte 0x8
; IASM-NEXT: .byte 0x10
; IASM-NEXT: .byte 0x9d ; IASM-NEXT: .byte 0x9d
; IASM-NEXT: .byte 0xe5 ; IASM-NEXT: .byte 0xe5
; IASM-NEXT: .byte 0x4 ; IASM-NEXT: .byte 0x4
; IASM-NEXT: .byte 0x10 ; IASM-NEXT: .byte 0x20
; IASM-NEXT: .byte 0x9d ; IASM-NEXT: .byte 0x9d
; IASM-NEXT: .byte 0xe5 ; IASM-NEXT: .byte 0xe5
; IASM-NEXT: .byte 0x1 ; IASM-NEXT: .byte 0x2
; IASM-NEXT: .byte 0x0 ; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x50 ; IASM-NEXT: .byte 0x51
; IASM-NEXT: .byte 0xe1 ; IASM-NEXT: .byte 0xe1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0xa0
; IASM-NEXT: .byte 0xa3
; IASM-NEXT: .byte 0x1 ; IASM-NEXT: .byte 0x1
; IASM-NEXT: .byte 0x0 ; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0xa0 ; IASM-NEXT: .byte 0xa0
...@@ -96,23 +96,20 @@ define internal void @mult_fwd_branches(i32 %a, i32 %b) { ...@@ -96,23 +96,20 @@ define internal void @mult_fwd_branches(i32 %a, i32 %b) {
br i1 %cmp, label %then, label %else br i1 %cmp, label %then, label %else
; ASM-NEXT: ldrb r0, [sp] ; ASM-NEXT: ldrb r0, [sp]
; ASM-NEXT: uxtb r0, r0 ; ASM-NEXT: tst r0, #1
; ASM-NEXT: cmp r0, #0
; ASM-NEXT: bne .Lmult_fwd_branches$then ; ASM-NEXT: bne .Lmult_fwd_branches$then
; ASM-NEXT: b .Lmult_fwd_branches$else ; ASM-NEXT: b .Lmult_fwd_branches$else
; DIS-NEXT: 24: e5dd0000 ; DIS-NEXT: 24: e5dd0000
; DIS-NEXT: 28: e6ef0070 ; DIS-NEXT: 28: e3100001
; DIS-NEXT: 2c: e3500000 ; DIS-NEXT: 2c: 1a000000
; DIS-NEXT: 30: 1a000000 ; DIS-NEXT: 30: ea000000
; DIS-NEXT: 34: ea000000
; IASM-NEXT: ldrb r0, [sp] ; IASM-NEXT: ldrb r0, [sp]
; IASM-NEXT: uxtb r0, r0
; IASM-NEXT: .byte 0x1
; IASM-NEXT: .byte 0x0 ; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0 ; IASM-NEXT: .byte 0x10
; IASM-NEXT: .byte 0x50
; IASM-NEXT: .byte 0xe3 ; IASM-NEXT: .byte 0xe3
; IASM-NEXT: .byte 0x0 ; IASM-NEXT: .byte 0x0
...@@ -132,7 +129,7 @@ then: ...@@ -132,7 +129,7 @@ then:
br label %end br label %end
; ASM-NEXT: b .Lmult_fwd_branches$end ; ASM-NEXT: b .Lmult_fwd_branches$end
; DIS-NEXT: 38: ea000000 ; DIS-NEXT: 34: ea000000
; IASM-NEXT: .byte 0x0 ; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0 ; IASM-NEXT: .byte 0x0
...@@ -146,7 +143,7 @@ else: ...@@ -146,7 +143,7 @@ else:
br label %end br label %end
; ASM-NEXT: b .Lmult_fwd_branches$end ; ASM-NEXT: b .Lmult_fwd_branches$end
; DIS-NEXT: 3c: eaffffff ; DIS-NEXT: 38: eaffffff
; IASM-NEXT: .byte 0xff ; IASM-NEXT: .byte 0xff
; IASM-NEXT: .byte 0xff ; IASM-NEXT: .byte 0xff
...@@ -163,8 +160,8 @@ end: ...@@ -163,8 +160,8 @@ end:
; ASM-NEXT: add sp, sp, #12 ; ASM-NEXT: add sp, sp, #12
; ASM-NEXT: bx lr ; ASM-NEXT: bx lr
; DIS-NEXT: 40: e28dd00c ; DIS-NEXT: 3c: e28dd00c
; DIS-NEXT: 44: e12fff1e ; DIS-NEXT: 40: e12fff1e
; IASM-NEXT: .byte 0xc ; IASM-NEXT: .byte 0xc
; IASM-NEXT: .byte 0xd0 ; IASM-NEXT: .byte 0xd0
......
...@@ -850,10 +850,7 @@ entry: ...@@ -850,10 +850,7 @@ entry:
; ARM32-LABEL: trunc64To1 ; ARM32-LABEL: trunc64To1
; ARM32-OM1: and r0, r0, #1 ; ARM32-OM1: and r0, r0, #1
; ARM32-OM1: and r0, r0, #1 ; ARM32-O2: 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:
...@@ -924,12 +921,10 @@ entry: ...@@ -924,12 +921,10 @@ entry:
; OPTM1: sar {{.*}},0x1f ; OPTM1: sar {{.*}},0x1f
; ARM32-LABEL: sext1To64 ; ARM32-LABEL: sext1To64
; ARM32-OM1: lsl {{.*}}, #31 ; ARM32: mov {{.*}}, #0
; ARM32-OM1: asr {{.*}}, #31 ; ARM32: tst {{.*}}, #1
; ARM32-O2: tst r0, #1 ; ARM32: mvn {{.*}}, #0
; ARM32-O2: mvn [[M1:r[0-9]+]], #0 ; ARM32: movne
; 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:
...@@ -998,11 +993,9 @@ entry: ...@@ -998,11 +993,9 @@ entry:
; OPTM1: mov {{.*}},0x0 ; OPTM1: mov {{.*}},0x0
; ARM32-LABEL: zext1To64 ; ARM32-LABEL: zext1To64
; ARM32-OM1: and {{.*}}, #1 ; ARM32: and {{.*}}, #1
; ARM32-OM1: mov {{.*}}, #0 ; ARM32: mov {{.*}}, #0
; ARM32-O2: tst r0, #1 ; ARM32: bx
; 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:
...@@ -1061,18 +1054,15 @@ if.end3: ; preds = %if.then2, %if.end ...@@ -1061,18 +1054,15 @@ if.end3: ; preds = %if.then2, %if.end
; ARM32-LABEL: icmpEq64 ; ARM32-LABEL: icmpEq64
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32-OM1: movne ; ARM32-OM1: tst
; ARM32-OM1: moveq ; ARM32: bne
; ARM32-OM1: cmp ; ARM32: bl {{.*}} <func>
; ARM32-O2: bne
; ARM32: bl
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32-OM1: movne ; ARM32-OM1: tst
; ARM32-OM1: moveq ; ARM32: bne
; ARM32-OM1: cmp ; ARM32: bl {{.*}} <func>
; ARM32-O2: bne ; ARM32: bx
; ARM32: bl
declare void @func() declare void @func()
...@@ -1133,16 +1123,14 @@ if.end3: ; preds = %if.end, %if.then2 ...@@ -1133,16 +1123,14 @@ if.end3: ; preds = %if.end, %if.then2
; ARM32-LABEL: icmpNe64 ; ARM32-LABEL: icmpNe64
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32-OM1: moveq ; ARM32-OM1: tst
; ARM32-OM1: movne ; ARM32-OM1: bne
; ARM32-OM1: cmp
; ARM32-O2: beq ; ARM32-O2: beq
; ARM32: bl ; ARM32: bl {{.*}} <func>
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32-OM1: moveq ; ARM32-OM1: tst
; ARM32-OM1: movne ; ARM32-OM1: bne
; ARM32-OM1: cmp
; ARM32-O2: beq ; ARM32-O2: beq
; ARM32: bl ; ARM32: bl
...@@ -1189,16 +1177,14 @@ if.end3: ; preds = %if.then2, %if.end ...@@ -1189,16 +1177,14 @@ if.end3: ; preds = %if.then2, %if.end
; ARM32-LABEL: icmpGt64 ; ARM32-LABEL: icmpGt64
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32-OM1: movls ; ARM32-OM1: tst
; ARM32-OM1: movhi ; ARM32-OM1: bne
; ARM32-OM1: cmp
; ARM32-O2: bls ; ARM32-O2: bls
; ARM32: bl ; ARM32: bl
; ARM32: cmp ; ARM32: cmp
; ARM32: sbcs ; ARM32: sbcs
; ARM32-OM1: movge ; ARM32-OM1: tst
; ARM32-OM1: movlt ; ARM32-OM1: bne
; ARM32-OM1: cmp
; ARM32-O2: bge ; ARM32-O2: bge
; ARM32: bl ; ARM32: bl
...@@ -1245,16 +1231,14 @@ if.end3: ; preds = %if.end, %if.then2 ...@@ -1245,16 +1231,14 @@ if.end3: ; preds = %if.end, %if.then2
; ARM32-LABEL: icmpGe64 ; ARM32-LABEL: icmpGe64
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32-OM1: movcc ; ARM32-OM1: tst
; ARM32-OM1: movcs ; ARM32-OM1: bne
; ARM32-OM1: cmp
; ARM32-O2: bcc ; ARM32-O2: bcc
; ARM32: bl ; ARM32: bl
; ARM32: cmp ; ARM32: cmp
; ARM32: sbcs ; ARM32: sbcs
; ARM32-OM1: movlt ; ARM32-OM1: tst
; ARM32-OM1: movge ; ARM32-OM1: bne
; ARM32-OM1: cmp
; ARM32-O2: blt ; ARM32-O2: blt
; ARM32: bl ; ARM32: bl
...@@ -1301,16 +1285,14 @@ if.end3: ; preds = %if.then2, %if.end ...@@ -1301,16 +1285,14 @@ if.end3: ; preds = %if.then2, %if.end
; ARM32-LABEL: icmpLt64 ; ARM32-LABEL: icmpLt64
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32-OM1: movcs ; ARM32-OM1: tst
; ARM32-OM1: movcc ; ARM32-OM1: bne
; ARM32-OM1: cmp
; ARM32-O2: bcs ; ARM32-O2: bcs
; ARM32: bl ; ARM32: bl
; ARM32: cmp ; ARM32: cmp
; ARM32: sbcs ; ARM32: sbcs
; ARM32-OM1: movge ; ARM32-OM1: tst
; ARM32-OM1: movlt ; ARM32-OM1: bne
; ARM32-OM1: cmp
; ARM32-O2: bge ; ARM32-O2: bge
; ARM32: bl ; ARM32: bl
...@@ -1357,15 +1339,14 @@ if.end3: ; preds = %if.end, %if.then2 ...@@ -1357,15 +1339,14 @@ if.end3: ; preds = %if.end, %if.then2
; ARM32-LABEL: icmpLe64 ; ARM32-LABEL: icmpLe64
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32-OM1: movhi ; ARM32-OM1: tst
; ARM32-OM1: movls ; ARM32-OM1: bne
; ARM32-OM1: cmp
; ARM32-O2: bhi ; ARM32-O2: bhi
; ARM32: bl ; ARM32: bl
; ARM32: cmp ; ARM32: cmp
; ARM32: sbcs ; ARM32: sbcs
; ARM32-OM1: movlt ; ARM32-OM1: tst
; ARM32-OM1: movge ; ARM32-OM1: bne
; ARM32-O2: blt ; ARM32-O2: blt
; ARM32: bl ; ARM32: bl
...@@ -1384,7 +1365,7 @@ entry: ...@@ -1384,7 +1365,7 @@ entry:
; OPTM1: je ; OPTM1: je
; ARM32-LABEL: icmpEq64Bool ; ARM32-LABEL: icmpEq64Bool
; ARM32: movne ; ARM32: mov
; ARM32: moveq ; ARM32: moveq
define internal i32 @icmpNe64Bool(i64 %a, i64 %b) { define internal i32 @icmpNe64Bool(i64 %a, i64 %b) {
...@@ -1402,7 +1383,7 @@ entry: ...@@ -1402,7 +1383,7 @@ entry:
; OPTM1: jne ; OPTM1: jne
; ARM32-LABEL: icmpNe64Bool ; ARM32-LABEL: icmpNe64Bool
; ARM32: moveq ; ARM32: mov
; ARM32: movne ; ARM32: movne
define internal i32 @icmpSgt64Bool(i64 %a, i64 %b) { define internal i32 @icmpSgt64Bool(i64 %a, i64 %b) {
...@@ -1426,9 +1407,9 @@ entry: ...@@ -1426,9 +1407,9 @@ entry:
; OPTM1: ja ; OPTM1: ja
; ARM32-LABEL: icmpSgt64Bool ; ARM32-LABEL: icmpSgt64Bool
; ARM32: mov
; ARM32: cmp ; ARM32: cmp
; ARM32: sbcs ; ARM32: sbcs
; ARM32: movge
; ARM32: movlt ; ARM32: movlt
define internal i32 @icmpUgt64Bool(i64 %a, i64 %b) { define internal i32 @icmpUgt64Bool(i64 %a, i64 %b) {
...@@ -1452,9 +1433,9 @@ entry: ...@@ -1452,9 +1433,9 @@ entry:
; OPTM1: ja ; OPTM1: ja
; ARM32-LABEL: icmpUgt64Bool ; ARM32-LABEL: icmpUgt64Bool
; ARM32: mov
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32: movls
; ARM32: movhi ; ARM32: movhi
define internal i32 @icmpSge64Bool(i64 %a, i64 %b) { define internal i32 @icmpSge64Bool(i64 %a, i64 %b) {
...@@ -1478,9 +1459,9 @@ entry: ...@@ -1478,9 +1459,9 @@ entry:
; OPTM1: jae ; OPTM1: jae
; ARM32-LABEL: icmpSge64Bool ; ARM32-LABEL: icmpSge64Bool
; ARM32: mov
; ARM32: cmp ; ARM32: cmp
; ARM32: sbcs ; ARM32: sbcs
; ARM32: movlt
; ARM32: movge ; ARM32: movge
define internal i32 @icmpUge64Bool(i64 %a, i64 %b) { define internal i32 @icmpUge64Bool(i64 %a, i64 %b) {
...@@ -1504,9 +1485,9 @@ entry: ...@@ -1504,9 +1485,9 @@ entry:
; OPTM1: jae ; OPTM1: jae
; ARM32-LABEL: icmpUge64Bool ; ARM32-LABEL: icmpUge64Bool
; ARM32: mov
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32: movcc
; ARM32: movcs ; ARM32: movcs
define internal i32 @icmpSlt64Bool(i64 %a, i64 %b) { define internal i32 @icmpSlt64Bool(i64 %a, i64 %b) {
...@@ -1530,9 +1511,9 @@ entry: ...@@ -1530,9 +1511,9 @@ entry:
; OPTM1: jb ; OPTM1: jb
; ARM32-LABEL: icmpSlt64Bool ; ARM32-LABEL: icmpSlt64Bool
; ARM32: mov
; ARM32: cmp ; ARM32: cmp
; ARM32: sbcs ; ARM32: sbcs
; ARM32: movge
; ARM32: movlt ; ARM32: movlt
define internal i32 @icmpUlt64Bool(i64 %a, i64 %b) { define internal i32 @icmpUlt64Bool(i64 %a, i64 %b) {
...@@ -1556,9 +1537,9 @@ entry: ...@@ -1556,9 +1537,9 @@ entry:
; OPTM1: jb ; OPTM1: jb
; ARM32-LABEL: icmpUlt64Bool ; ARM32-LABEL: icmpUlt64Bool
; ARM32: mov
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32: movcs
; ARM32: movcc ; ARM32: movcc
define internal i32 @icmpSle64Bool(i64 %a, i64 %b) { define internal i32 @icmpSle64Bool(i64 %a, i64 %b) {
...@@ -1582,9 +1563,9 @@ entry: ...@@ -1582,9 +1563,9 @@ entry:
; OPTM1: jbe ; OPTM1: jbe
; ARM32-LABEL: icmpSle64Bool ; ARM32-LABEL: icmpSle64Bool
; ARM32: mov
; ARM32: cmp ; ARM32: cmp
; ARM32: sbcs ; ARM32: sbcs
; ARM32: movlt
; ARM32: movge ; ARM32: movge
define internal i32 @icmpUle64Bool(i64 %a, i64 %b) { define internal i32 @icmpUle64Bool(i64 %a, i64 %b) {
...@@ -1608,9 +1589,9 @@ entry: ...@@ -1608,9 +1589,9 @@ entry:
; OPTM1: jbe ; OPTM1: jbe
; ARM32-LABEL: icmpUle64Bool ; ARM32-LABEL: icmpUle64Bool
; ARM32: mov
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32: movhi
; ARM32: movls ; ARM32: movls
define internal i64 @load64(i32 %a) { define internal i64 @load64(i32 %a) {
...@@ -1701,9 +1682,7 @@ entry: ...@@ -1701,9 +1682,7 @@ entry:
; ARM32-LABEL: select64VarVar ; ARM32-LABEL: select64VarVar
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32-OM1: movcs ; ARM32-OM1: tst
; ARM32-OM1: movcc
; ARM32-OM1: cmp
; ARM32-OM1: movne ; ARM32-OM1: movne
; ARM32-O2: movcc ; ARM32-O2: movcc
; ARM32-OM1: movne ; ARM32-OM1: movne
...@@ -1734,19 +1713,17 @@ entry: ...@@ -1734,19 +1713,17 @@ entry:
; OPTM1: cmovne ; OPTM1: cmovne
; ARM32-LABEL: select64VarConst ; ARM32-LABEL: select64VarConst
; ARM32: mov
; ARM32: mov
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32-OM1: movcs ; ARM32-OM1: tst
; ARM32-OM1: movcc
; ARM32-OM1: cmp
; ARM32: movw
; ARM32: movt
; ARM32-OM1: movne ; ARM32-OM1: movne
; ARM32-O2: movcc ; ARM32-O2: movcc
; ARM32: movw
; ARM32: movt
; ARM32-OM1: movne ; ARM32-OM1: movne
; ARM32-O2: movcc ; ARM32-O2: movcc
; ARM32-O2: mov
; ARM32-O2: mov
define internal i64 @select64ConstVar(i64 %a, i64 %b) { define internal i64 @select64ConstVar(i64 %a, i64 %b) {
entry: entry:
...@@ -1775,9 +1752,7 @@ entry: ...@@ -1775,9 +1752,7 @@ entry:
; ARM32-LABEL: select64ConstVar ; ARM32-LABEL: select64ConstVar
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32-OM1: movcs ; ARM32-OM1: tst
; ARM32-OM1: movcc
; ARM32-OM1: cmp
; ARM32: movw ; ARM32: movw
; ARM32: movt ; ARM32: movt
; ARM32-OM1: movne ; ARM32-OM1: movne
......
...@@ -85,7 +85,7 @@ branch2: ...@@ -85,7 +85,7 @@ branch2:
; ARM32-LABEL: no_fold_cmp_br_liveout ; ARM32-LABEL: no_fold_cmp_br_liveout
; ARM32: cmp ; ARM32: cmp
; ARM32: movlt [[REG:r[0-9]+]] ; ARM32: movlt [[REG:r[0-9]+]]
; ARM32: cmp [[REG]], #0 ; ARM32: tst [[REG]], #1
; ARM32: beq ; ARM32: beq
...@@ -108,11 +108,11 @@ branch2: ...@@ -108,11 +108,11 @@ 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: cmp r0, r1 ; ARM32: tst [[R]], #1
; ARM32: bge ; ARM32: beq
; ARM32: bx lr ; ARM32: bx lr
; ARM32: mov r0, #2 ; ARM32: mov r0, #2
; ARM32: bx lr ; ARM32: bx lr
...@@ -168,10 +168,10 @@ entry: ...@@ -168,10 +168,10 @@ entry:
; CHECK: cmovl ; CHECK: cmovl
; CHECK: cmovl ; CHECK: cmovl
; ARM32-LABEL: fold_cmp_select_64_undef ; ARM32-LABEL: fold_cmp_select_64_undef
; ARM32: mov
; ARM32: mov
; ARM32: cmp {{r[0-9]+}}, r0 ; ARM32: cmp {{r[0-9]+}}, r0
; ARM32: movge
; ARM32: movlt ; ARM32: movlt
; ARM32: movge
; ARM32: movlt ; ARM32: movlt
; ARM32: bx lr ; ARM32: bx lr
...@@ -218,14 +218,17 @@ entry: ...@@ -218,14 +218,17 @@ entry:
; CHECK: add ; CHECK: add
; CHECK: add ; CHECK: add
; ARM32-LABEL: fold_cmp_select_multi ; ARM32-LABEL: fold_cmp_select_multi
; ARM32: cmp r0, r1 ; ARM32: mov
; ARM32: movlt {{r[0-9]+}}, r0 ; ARM32: cmp
; ARM32: cmp r0, r1 ; ARM32: movlt {{.*}}, #1
; ARM32: movlt {{r[0-9]+}}, r1 ; ARM32: mov
; ARM32: cmp r0, r1 ; ARM32: tst {{.*}}, #1
; ARM32: movlt {{r[0-9]+}}, #123 ; ARM32: movne
; ARM32: add ; ARM32: mov
; ARM32: add ; ARM32: tst {{.*}}, #1
; ARM32: movne
; ARM32: tst {{.*}}, #1
; ARM32: movne {{.*}}, #123
; ARM32: bx lr ; ARM32: bx lr
...@@ -254,22 +257,17 @@ next: ...@@ -254,22 +257,17 @@ next:
; CHECK: add ; CHECK: add
; 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: mov
; ARM32: cmp r0, r1 ; ARM32: cmp r0, r1
; ARM32: movge [[T0:r[0-9]+]], #0 ; ARM32: movlt
; ARM32: movlt [[T0]], #1 ; ARM32: mov
; ARM32: uxtb [[T1:r[0-9]+]], [[T1]] ; ARM32: tst
; ARM32-NEXT: cmp [[T1]], #0 ; ARM32: movne
; ARM32: movne [[T2:r[0-9]+]], r0 ; ARM32: mov
; ARM32: uxtb [[T3:r[0-9]+]], [[T3]] ; ARM32: tst
; ARM32-NEXT: cmp [[T3]], #0 ; ARM32: movne
; ARM32: movne [[T4:r[0-9]+]], r1 ; ARM32: tst
; ARM32-LABEL: .Lno_fold_cmp_select_multi_liveout$next: ; ARM32: movne
; ARM32: uxtb [[T5:r[0-9]+]], [[T5]]
; ARM32: cmp [[T5]], #0
; ARM32: movne [[T6:r[0-9]+]], #123
; ARM32: add
; 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.
...@@ -300,19 +298,133 @@ entry: ...@@ -300,19 +298,133 @@ 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
; ARM32: cmp r0, r1 ; ARM32: cmp r0, r1
; ARM32: movge [[R0:r[0-9]+]] ; ARM32: movlt
; ARM32: movlt [[R0]] ; ARM32: mov
; ARM32: cmp r0, r1 ; ARM32: tst
; ARM32: movge [[R1:r[0-9]+]] ; ARM32: movne
; ARM32: movlt [[R1]] ; ARM32: mov
; ARM32: cmp r0, r1 ; ARM32: tst
; ARM32: movge [[R2:r[0-9]+]] ; ARM32: movne
; ARM32: movlt [[R2]] ; ARM32: tst
; ARM32: cmp r0, r1 ; ARM32: movne
; ARM32: movge [[R3:r[0-9]+]]
; ARM32: movlt [[R3]]
; ARM32: add
; ARM32: add
; ARM32: add
; ARM32: bx lr ; ARM32: bx lr
define internal i32 @br_i1_folding2_and(i32 %arg1, i32 %arg2) {
%t0 = trunc i32 %arg1 to i1
%t1 = trunc i32 %arg2 to i1
%t2 = and i1 %t0, %t1
br i1 %t2, label %target_true, label %target_false
target_true:
ret i32 1
target_false:
ret i32 0
}
; ARM32-LABEL: br_i1_folding2_and
; ARM32: tst r0, #1
; ARM32: beq {{.*}}target_false
; ARM32: tst r1, #1
; ARM32: beq {{.*}}target_false
define internal i32 @br_i1_folding2_or(i32 %arg1, i32 %arg2) {
%t0 = trunc i32 %arg1 to i1
%t1 = trunc i32 %arg2 to i1
%t2 = or i1 %t0, %t1
br i1 %t2, label %target_true, label %target_false
target_true:
ret i32 1
target_false:
ret i32 0
}
; ARM32-LABEL: br_i1_folding2_or
; ARM32: tst r0, #1
; ARM32: bne {{.*}}target_true
; ARM32: tst r1, #1
; ARM32: beq {{.*}}target_false
define internal i32 @br_i1_folding3_and_or(i32 %arg1, i32 %arg2, i32 %arg3) {
%t0 = trunc i32 %arg1 to i1
%t1 = trunc i32 %arg2 to i1
%t2 = trunc i32 %arg3 to i1
%t3 = and i1 %t0, %t1
%t4 = or i1 %t3, %t2
br i1 %t4, label %target_true, label %target_false
target_true:
ret i32 1
target_false:
ret i32 0
}
; ARM32-LABEL: br_i1_folding3_and_or
; ARM32: tst r0, #1
; ARM32: beq
; ARM32: tst r1, #1
; ARM32: bne {{.*}}target_true
; ARM32: tst r2, #1
; ARM32: beq {{.*}}target_false
define internal i32 @br_i1_folding3_or_and(i32 %arg1, i32 %arg2, i32 %arg3) {
%t0 = trunc i32 %arg1 to i1
%t1 = trunc i32 %arg2 to i1
%t2 = trunc i32 %arg3 to i1
%t3 = or i1 %t0, %t1
%t4 = and i1 %t3, %t2
br i1 %t4, label %target_true, label %target_false
target_true:
ret i32 1
target_false:
ret i32 0
}
; ARM32-LABEL: br_i1_folding3_or_and
; ARM32: tst r0, #1
; ARM32: bne
; ARM32: tst r1, #1
; ARM32: beq {{.*}}target_false
; ARM32: tst r2, #1
; ARM32: beq {{.*}}target_false
define internal i32 @br_i1_folding4(i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4,
i32 %arg5) {
%t0 = trunc i32 %arg1 to i1
%t1 = trunc i32 %arg2 to i1
%t2 = trunc i32 %arg3 to i1
%t3 = trunc i32 %arg4 to i1
%t4 = trunc i32 %arg5 to i1
%t5 = or i1 %t0, %t1
%t6 = and i1 %t5, %t2
%t7 = and i1 %t3, %t4
%t8 = or i1 %t6, %t7
br i1 %t8, label %target_true, label %target_false
target_true:
ret i32 1
target_false:
ret i32 0
}
; ARM32-LABEL: br_i1_folding4
; ARM32: tst r0, #1
; ARM32: bne
; ARM32: tst r1, #1
; ARM32: beq
; ARM32: tst r2, #1
; ARM32: bne {{.*}}target_true
; ARM32: tst r3, #1
; ARM32: beq {{.*}}target_false
; ARM32: tst r4, #1
; ARM32: beq {{.*}}target_false
...@@ -92,7 +92,6 @@ target: ...@@ -92,7 +92,6 @@ target:
; OM1: call ; OM1: call
; OM1: ret ; OM1: ret
; 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: bge ; ARM32O2-NEXT: bge
...@@ -102,10 +101,10 @@ target: ...@@ -102,10 +101,10 @@ target:
; ARM32O2: bx lr ; ARM32O2: bx lr
; ARM32OM1-LABEL: testCondFallthroughToNextBlock ; ARM32OM1-LABEL: testCondFallthroughToNextBlock
; ARM32OM1: mov {{.*}}, #0
; ARM32OM1: cmp {{.*}}, #123 ; ARM32OM1: cmp {{.*}}, #123
; ARM32OM1: movlt {{.*}}, #0
; ARM32OM1: movge {{.*}}, #1 ; ARM32OM1: movge {{.*}}, #1
; ARM32OM1: cmp {{.*}}, #0 ; ARM32OM1: tst {{.*}}, #1
; ARM32OM1: bne ; ARM32OM1: bne
; ARM32OM1: b ; ARM32OM1: b
; ARM32OM1: bl ; ARM32OM1: bl
...@@ -161,7 +160,7 @@ target: ...@@ -161,7 +160,7 @@ target:
; ARM32OM1-LABEL: testCondTargetNextBlock ; ARM32OM1-LABEL: testCondTargetNextBlock
; ARM32OM1: cmp {{.*}}, #123 ; ARM32OM1: cmp {{.*}}, #123
; ARM32OM1: movge {{.*}}, #1 ; ARM32OM1: movge {{.*}}, #1
; ARM32OM1: cmp {{.*}}, #0 ; ARM32OM1: tst {{.*}}, #1
; ARM32OM1: bne ; ARM32OM1: bne
; ARM32OM1: b ; ARM32OM1: b
; ARM32OM1: bl ; ARM32OM1: bl
......
...@@ -51,14 +51,12 @@ declare void @useInt(i32 %x) ...@@ -51,14 +51,12 @@ declare void @useInt(i32 %x)
; CHECK: ret ; CHECK: ret
; ARM32-LABEL: testSelect ; ARM32-LABEL: testSelect
; ARM32: cmp ; ARM32: cmp
; ARM32-OM1: cmp
; ARM32: bl {{.*}} useInt ; ARM32: bl {{.*}} useInt
; ARM32: cmp
; ARM32-Om1: cmp
; ARM32-Om1: mov {{.*}}, #20 ; ARM32-Om1: mov {{.*}}, #20
; ARM32-O2: mov [[REG:r[0-9]+]], #20
; ARM32: tst
; ARM32-Om1: movne {{.*}}, #10 ; ARM32-Om1: movne {{.*}}, #10
; ARM32-O2: movle [[REG:r[0-9]+]], #20 ; ARM32-O2: movne [[REG]], #10
; ARM32-O2: movgt [[REG]], #10
; ARM32: bl {{.*}} useInt ; ARM32: bl {{.*}} useInt
; ARM32: bl {{.*}} useInt ; ARM32: bl {{.*}} useInt
; ARM32: bl {{.*}} useInt ; ARM32: bl {{.*}} useInt
......
...@@ -15,8 +15,6 @@ ...@@ -15,8 +15,6 @@
; 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
; TODO(jvoung): test this.
; Test that and with true uses immediate 1, not -1. ; Test that and with true uses immediate 1, not -1.
define internal i32 @testAndTrue(i32 %arg) { define internal i32 @testAndTrue(i32 %arg) {
entry: entry:
...@@ -66,9 +64,7 @@ entry: ...@@ -66,9 +64,7 @@ entry:
; CHECK-LABEL: testTrunc ; CHECK-LABEL: testTrunc
; CHECK: and {{.*}},0x1 ; CHECK: and {{.*}},0x1
; ARM32-LABEL: testTrunc ; ARM32-LABEL: testTrunc
; ARM32: tst r0, #1 ; ARM32: and {{.*}}, #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) {
...@@ -84,10 +80,8 @@ entry: ...@@ -84,10 +80,8 @@ 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: tst r0, #1 ; ARM32: {{.*}}, #1
; ARM32: moveq [[REG:r[0-9]*]], #0 ; ARM32: uxtb
; 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) {
...@@ -105,10 +99,8 @@ entry: ...@@ -105,10 +99,8 @@ entry:
; CHECK-NOT: and [[REG]],0x1 ; CHECK-NOT: and [[REG]],0x1
; ARM32-LABEL: testZextI16 ; ARM32-LABEL: testZextI16
; ARM32: tst r0, #1 ; ARM32: and {{.*}}, #1
; ARM32: moveq [[REG:r[0-9]*]], #0 ; ARM32: uxth
; ARM32: movne [[REG]], #1
; ARM32: uxth [[REG]]
; Test zext to i32. ; Test zext to i32.
define internal i32 @testZextI32(i32 %arg) { define internal i32 @testZextI32(i32 %arg) {
...@@ -124,9 +116,7 @@ entry: ...@@ -124,9 +116,7 @@ entry:
; CHECK: movzx ; CHECK: movzx
; CHECK-NOT: and {{.*}},0x1 ; CHECK-NOT: and {{.*}},0x1
; ARM32-LABEL: testZextI32 ; ARM32-LABEL: testZextI32
; 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) {
...@@ -142,10 +132,8 @@ entry: ...@@ -142,10 +132,8 @@ entry:
; CHECK: movzx ; CHECK: movzx
; CHECK: mov {{.*}},0x0 ; CHECK: mov {{.*}},0x0
; ARM32-LABEL: testZextI64 ; ARM32-LABEL: testZextI64
; 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,11 +151,11 @@ entry: ...@@ -163,11 +151,11 @@ entry:
; CHECK-NEXT: sar [[REG]],0x7 ; CHECK-NEXT: sar [[REG]],0x7
; ;
; ARM32-LABEL: testSextI8 ; ARM32-LABEL: testSextI8
; ARM32: tst r0, #1 ; ARM32: mov {{.*}}, #0
; ARM32: mvn [[REG_M1:r[0-9]*]], #0 ; ARM32: tst {{.*}}, #1
; ARM32: moveq [[REG:r[0-9]*]], #0 ; ARM32: mvn {{.*}}, #0
; ARM32: movne [[REG]], [[REG_M1]] ; ARM32: movne
; ARM32: sxtb [[REG]] ; ARM32: sxtb
; Test sext to i16. ; Test sext to i16.
define internal i32 @testSextI16(i32 %arg) { define internal i32 @testSextI16(i32 %arg) {
...@@ -186,11 +174,11 @@ entry: ...@@ -186,11 +174,11 @@ entry:
; CHECK-NEXT: sar [[REG]],0xf ; CHECK-NEXT: sar [[REG]],0xf
; ARM32-LABEL: testSextI16 ; ARM32-LABEL: testSextI16
; ARM32: tst r0, #1 ; ARM32: mov {{.*}}, #0
; ARM32: mvn [[REG_M1:r[0-9]*]], #0 ; ARM32: tst {{.*}}, #1
; ARM32: moveq [[REG:r[0-9]*]], #0 ; ARM32: mvn {{.*}}, #0
; ARM32: movne [[REG]], [[REG_M1]] ; ARM32: movne
; ARM32: sxth [[REG]] ; ARM32: sxth
; Test sext to i32. ; Test sext to i32.
define internal i32 @testSextI32(i32 %arg) { define internal i32 @testSextI32(i32 %arg) {
...@@ -208,10 +196,10 @@ entry: ...@@ -208,10 +196,10 @@ entry:
; CHECK-NEXT: sar [[REG]],0x1f ; CHECK-NEXT: sar [[REG]],0x1f
; ARM32-LABEL: testSextI32 ; ARM32-LABEL: testSextI32
; ARM32: tst r0, #1 ; ARM32: mov {{.*}}, #0
; ARM32: mvn [[REG_M1:r[0-9]*]], #0 ; ARM32: tst {{.*}}, #1
; ARM32: moveq [[REG:r[0-9]*]], #0 ; ARM32: mvn {{.*}}, #0
; ARM32: movne [[REG]], [[REG_M1]] ; ARM32: movne
; Test sext to i64. ; Test sext to i64.
define internal i64 @testSextI64(i32 %arg) { define internal i64 @testSextI64(i32 %arg) {
...@@ -229,11 +217,11 @@ entry: ...@@ -229,11 +217,11 @@ entry:
; CHECK-NEXT: sar [[REG]],0x1f ; CHECK-NEXT: sar [[REG]],0x1f
; ARM32-LABEL: testSextI64 ; ARM32-LABEL: testSextI64
; ARM32: tst r0, #1 ; ARM32: mov {{.*}}, #0
; ARM32: mvn [[REG_M1:r[0-9]*]], #0 ; ARM32: tst {{.*}}, #1
; ARM32: moveq [[REG:r[0-9]*]], #0 ; ARM32: mvn {{.*}}, #0
; ARM32: movne [[REG]], [[REG_M1]] ; ARM32: movne [[REG:r[0-9]+]]
; ARM32: mov r{{[0-9]+}}, [[REG]] ; ARM32: mov {{.*}}, [[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.
...@@ -248,9 +236,10 @@ define internal i32 @testSextTrue() { ...@@ -248,9 +236,10 @@ define internal i32 @testSextTrue() {
; CHECK-NEXT: shl ; CHECK-NEXT: shl
; CHECK-NEXT: sar ; CHECK-NEXT: sar
; ARM32-LABEL: testSextTrue ; ARM32-LABEL: testSextTrue
; ARM32: mov{{.*}}, #1 ; ARM32: mov {{.*}}, #0
; ARM32: lsl ; ARM32: tst {{.*}}, #1
; ARM32: asr ; ARM32: mvn {{.*}}, #0
; ARM32: movne
define internal i32 @testZextTrue() { define internal i32 @testZextTrue() {
%result = zext i1 true to i32 %result = zext i1 true to i32
......
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