Skip to content

Commit 6d4cfab

Browse files
rmacnak-googleCommit Queue
authored andcommitted
[vm, compiler] Combine cset+sub into csetm for ARM64 IfThenElse.
TEST=ci Change-Id: I64f70325ceca589ee93663f651a784c9c833ce36 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/464763 Reviewed-by: Alexander Markov <[email protected]> Commit-Queue: Ryan Macnak <[email protected]>
1 parent d793fc0 commit 6d4cfab

File tree

5 files changed

+49
-17
lines changed

5 files changed

+49
-17
lines changed

runtime/vm/compiler/assembler/assembler_arm64.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2528,7 +2528,7 @@ class Assembler : public AssemblerBase {
25282528
return static_cast<Condition>((instr & kCondMask) >> kCondShift);
25292529
}
25302530
ASSERT(IsCompareAndBranch(instr));
2531-
return (instr & B24) ? EQ : NE; // cbz : cbnz
2531+
return (instr & B24) != 0 ? EQ : NE; // cbz : cbnz
25322532
}
25332533

25342534
int32_t EncodeImm19BranchCondition(Condition cond, int32_t instr) {
@@ -2542,7 +2542,7 @@ class Assembler : public AssemblerBase {
25422542

25432543
Condition DecodeImm14BranchCondition(int32_t instr) {
25442544
ASSERT(IsTestAndBranch(instr));
2545-
return (instr & B24) ? EQ : NE; // tbz : tbnz
2545+
return (instr & B24) != 0 ? EQ : NE; // tbz : tbnz
25462546
}
25472547

25482548
int32_t EncodeImm14BranchCondition(Condition cond, int32_t instr) {

runtime/vm/compiler/assembler/assembler_arm64_test.cc

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -412,21 +412,21 @@ ASSEMBLER_TEST_GENERATE(Overflow, assembler) {
412412
__ LoadImmediate(R3, 0x7FFFFFFFFFFFFFFF);
413413
__ adds(IP0, R2, Operand(R1)); // c_out = 1.
414414
__ adcs(IP0, R3, R0); // c_in = 1, c_out = 1, v = 1.
415-
__ csinc(R0, R0, R0, VS); // R0 = v ? R0 : R0 + 1.
415+
__ cset(R0, VS); // R0 = v ? 1 : 0
416416
__ ret();
417417
}
418418

419419
ASSEMBLER_TEST_RUN(Overflow, test) {
420420
typedef int64_t (*Int64Return)() DART_UNUSED;
421-
EXPECT_EQ(0, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
421+
EXPECT_EQ(1, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
422422
EXPECT_DISASSEMBLY(
423423
"movz r0, #0x0\n"
424424
"movz r1, #0x1\n"
425425
"movn r2, #0x0\n"
426426
"mov r3, 0x7fffffffffffffff\n"
427427
"adds tmp, r2, r1\n"
428428
"adcs tmp, r3, r0\n"
429-
"csinc r0, r0, r0, vs\n"
429+
"cset r0, vs\n"
430430
"ret\n");
431431
}
432432

@@ -481,21 +481,21 @@ ASSEMBLER_TEST_GENERATE(WordOverflow, assembler) {
481481
__ LoadImmediate(R3, 0x7FFFFFFF);
482482
__ addsw(IP0, R2, Operand(R1)); // c_out = 1.
483483
__ adcsw(IP0, R3, R0); // c_in = 1, c_out = 1, v = 1.
484-
__ csinc(R0, R0, R0, VS); // R0 = v ? R0 : R0 + 1.
484+
__ cset(R0, VS); // R0 = v ? 1 : 0
485485
__ ret();
486486
}
487487

488488
ASSEMBLER_TEST_RUN(WordOverflow, test) {
489489
typedef int64_t (*Int64Return)() DART_UNUSED;
490-
EXPECT_EQ(0, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
490+
EXPECT_EQ(1, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
491491
EXPECT_DISASSEMBLY(
492492
"movz r0, #0x0\n"
493493
"movz r1, #0x1\n"
494494
"mov r2, 0xffffffff\n"
495495
"mov r3, 0x7fffffff\n"
496496
"addws tmp, r2, r1\n"
497497
"adcws tmp, r3, r0\n"
498-
"csinc r0, r0, r0, vs\n"
498+
"cset r0, vs\n"
499499
"ret\n");
500500
}
501501

@@ -4165,7 +4165,7 @@ ASSEMBLER_TEST_RUN(CsincTrue, test) {
41654165
"movz r1, #0x2a\n"
41664166
"movz r2, #0x4d2\n"
41674167
"cmp r1, r2\n"
4168-
"cinc r0, r2, ge\n"
4168+
"csinc r0, r2, r1, lt\n"
41694169
"ret\n");
41704170
}
41714171

@@ -4245,6 +4245,31 @@ ASSEMBLER_TEST_RUN(CsnegTrue, test) {
42454245
"ret\n");
42464246
}
42474247

4248+
ASSEMBLER_TEST_GENERATE(CSelAliases, assembler) {
4249+
__ csel(R0, R1, R2, LT);
4250+
__ cset(R0, LT);
4251+
__ csetm(R0, LT);
4252+
__ csinc(R0, R1, R2, LT);
4253+
__ cinc(R0, R1, LT);
4254+
__ csinv(R0, R1, R2, LT);
4255+
__ cinv(R0, R1, LT);
4256+
__ csneg(R0, R1, R2, LT);
4257+
__ cneg(R0, R1, LT);
4258+
}
4259+
4260+
ASSEMBLER_TEST_RUN(CSelAliases, test) {
4261+
EXPECT_DISASSEMBLY(
4262+
"csel r0, r1, r2, lt\n"
4263+
"cset r0, lt\n"
4264+
"csetm r0, lt\n"
4265+
"csinc r0, r1, r2, lt\n"
4266+
"cinc r0, r1, lt\n"
4267+
"csinv r0, r1, r2, lt\n"
4268+
"cinv r0, r1, lt\n"
4269+
"csneg r0, r1, r2, lt\n"
4270+
"cneg r0, r1, lt\n");
4271+
}
4272+
42484273
ASSEMBLER_TEST_GENERATE(Ubfx, assembler) {
42494274
__ LoadImmediate(R1, 0x819);
42504275
__ LoadImmediate(R0, 0x5a5a5a5a); // Overwritten.

runtime/vm/compiler/assembler/disassembler_arm64.cc

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,13 +1307,21 @@ void ARM64Decoder::DecodeConditionalSelect(Instr* instr) {
13071307
Format(instr, "csel'sf 'rd, 'rn, 'rm, 'cond");
13081308
} else if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 1)) {
13091309
if (non_select) {
1310-
Format(instr, "csinc'sf 'rd, 'rn, 'rm, 'cond");
1310+
if (instr->RnField() == 31 && instr->RmField() == 31) {
1311+
Format(instr, "cset'sf 'rd, 'condinverted");
1312+
} else {
1313+
Format(instr, "cinc'sf 'rd, 'rn, 'condinverted");
1314+
}
13111315
} else {
1312-
Format(instr, "cinc'sf 'rd, 'rn, 'condinverted");
1316+
Format(instr, "csinc'sf 'rd, 'rn, 'rm, 'cond");
13131317
}
13141318
} else if ((instr->Bits(29, 2) == 2) && (instr->Bits(10, 2) == 0)) {
13151319
if (non_select) {
1316-
Format(instr, "cinv'sf 'rd, 'rn, 'condinverted");
1320+
if (instr->RnField() == 31 && instr->RmField() == 31) {
1321+
Format(instr, "csetm'sf 'rd, 'condinverted");
1322+
} else {
1323+
Format(instr, "cinv'sf 'rd, 'rn, 'condinverted");
1324+
}
13171325
} else {
13181326
Format(instr, "csinv'sf 'rd, 'rn, 'rm, 'cond");
13191327
}

runtime/vm/compiler/backend/il_arm64.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -610,19 +610,17 @@ void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
610610
intptr_t temp = true_value;
611611
true_value = false_value;
612612
false_value = temp;
613-
} else {
614613
true_condition = InvertCondition(true_condition);
615614
}
616615
}
617616

618-
__ cset(result, true_condition);
619-
620617
if (is_power_of_two_kind) {
621618
const intptr_t shift =
622619
Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value));
620+
__ cset(result, true_condition);
623621
__ LslImmediate(result, result, shift + kSmiTagSize);
624622
} else {
625-
__ sub(result, result, compiler::Operand(1));
623+
__ csetm(result, true_condition); // result = cond ? -1 : 0
626624
const int64_t val = Smi::RawValue(true_value) - Smi::RawValue(false_value);
627625
__ AndImmediate(result, result, val);
628626
if (false_value != 0) {

runtime/vm/constants_arm64.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,8 @@ class Instr {
16141614

16151615
static int64_t VFPExpandImm(uint8_t imm8) {
16161616
const int64_t sign = static_cast<int64_t>((imm8 & 0x80) >> 7) << 63;
1617-
const int64_t hi_exp = static_cast<int64_t>(!((imm8 & 0x40) >> 6)) << 62;
1617+
const int64_t hi_exp = static_cast<int64_t>(((imm8 & 0x40) >> 6) == 0)
1618+
<< 62;
16181619
const int64_t mid_exp = (((imm8 & 0x40) >> 6) == 0) ? 0 : (0xffLL << 54);
16191620
const int64_t low_exp = static_cast<int64_t>((imm8 & 0x30) >> 4) << 52;
16201621
const int64_t frac = static_cast<int64_t>(imm8 & 0x0f) << 48;

0 commit comments

Comments
 (0)