summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJuergen Ributzka <juergen@apple.com>2015-08-06 22:13:48 +0000
committerJuergen Ributzka <juergen@apple.com>2015-08-06 22:13:48 +0000
commit9f54dbe7a11d4d2140dd6269a3fe440fdf2cb0f2 (patch)
tree36d62d23e3a390a3e8688b2cc5c02f7206867312 /llvm/lib
parentb6dfd9490bf0a346248d921b110688b5a951cb5b (diff)
downloadbcm5719-llvm-9f54dbe7a11d4d2140dd6269a3fe440fdf2cb0f2.tar.gz
bcm5719-llvm-9f54dbe7a11d4d2140dd6269a3fe440fdf2cb0f2.zip
Revert "[AArch64][FastISel] Add more truncation tests." and "[AArch64][FastISel] Always use an AND instruction when truncating to non-legal types."
This reverts commit r243198 and 243304. Turns out this wasn't the correct fix for this problem. It works only within FastISel, but fails when the truncate is selected by SDAG. llvm-svn: 244287
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AArch64/AArch64FastISel.cpp55
1 files changed, 31 insertions, 24 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
index f74a9fa3bb0..280e5fc2b50 100644
--- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
@@ -3794,34 +3794,41 @@ bool AArch64FastISel::selectTrunc(const Instruction *I) {
return false;
bool SrcIsKill = hasTrivialKill(Op);
- // If we're truncating from i64/i32 to a smaller non-legal type then generate
- // an AND.
- uint64_t Mask = 0;
- switch (DestVT.SimpleTy) {
- default:
- // Trunc i64 to i32 is handled by the target-independent fast-isel.
- return false;
- case MVT::i1:
- Mask = 0x1;
- break;
- case MVT::i8:
- Mask = 0xff;
- break;
- case MVT::i16:
- Mask = 0xffff;
- break;
- }
+ // If we're truncating from i64 to a smaller non-legal type then generate an
+ // AND. Otherwise, we know the high bits are undefined and a truncate only
+ // generate a COPY. We cannot mark the source register also as result
+ // register, because this can incorrectly transfer the kill flag onto the
+ // source register.
+ unsigned ResultReg;
if (SrcVT == MVT::i64) {
+ uint64_t Mask = 0;
+ switch (DestVT.SimpleTy) {
+ default:
+ // Trunc i64 to i32 is handled by the target-independent fast-isel.
+ return false;
+ case MVT::i1:
+ Mask = 0x1;
+ break;
+ case MVT::i8:
+ Mask = 0xff;
+ break;
+ case MVT::i16:
+ Mask = 0xffff;
+ break;
+ }
// Issue an extract_subreg to get the lower 32-bits.
- SrcReg = fastEmitInst_extractsubreg(MVT::i32, SrcReg, SrcIsKill,
- AArch64::sub_32);
- SrcIsKill = true;
+ unsigned Reg32 = fastEmitInst_extractsubreg(MVT::i32, SrcReg, SrcIsKill,
+ AArch64::sub_32);
+ // Create the AND instruction which performs the actual truncation.
+ ResultReg = emitAnd_ri(MVT::i32, Reg32, /*IsKill=*/true, Mask);
+ assert(ResultReg && "Unexpected AND instruction emission failure.");
+ } else {
+ ResultReg = createResultReg(&AArch64::GPR32RegClass);
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
+ TII.get(TargetOpcode::COPY), ResultReg)
+ .addReg(SrcReg, getKillRegState(SrcIsKill));
}
- // Create the AND instruction which performs the actual truncation.
- unsigned ResultReg = emitAnd_ri(MVT::i32, SrcReg, SrcIsKill, Mask);
- assert(ResultReg && "Unexpected AND instruction emission failure.");
-
updateValueMap(I, ResultReg);
return true;
}
OpenPOWER on IntegriCloud