diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -432,6 +432,12 @@ // FIXME: X86 also checks for CMOV here. Do we need something similar? static inline bool isDef32(const SDNode &N) { unsigned Opc = N.getOpcode(); + + if (Opc == ISD::SIGN_EXTEND_INREG) { + SDValue Opr = N.getOperand(0); + return Opr->getOpcode() != ISD::TRUNCATE; + } + return Opc != ISD::TRUNCATE && Opc != TargetOpcode::EXTRACT_SUBREG && Opc != ISD::CopyFromReg && Opc != ISD::AssertSext && Opc != ISD::AssertZext; diff --git a/llvm/test/CodeGen/AArch64/aarch64-avoid-implicit-zext-for-SIGN_EXTEND_INREG.ll b/llvm/test/CodeGen/AArch64/aarch64-avoid-implicit-zext-for-SIGN_EXTEND_INREG.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/aarch64-avoid-implicit-zext-for-SIGN_EXTEND_INREG.ll @@ -0,0 +1,28 @@ +; RUN: llc -O3 -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s +@b = dso_local local_unnamed_addr global { [3 x i8], i8, i8, i8, i8, i8 } { [3 x i8] undef, i8 -64, i8 74, i8 -9, i8 -1, i8 7 }, align 8 +@c = common dso_local local_unnamed_addr global i64 0, align 8 +@.str = private unnamed_addr constant [9 x i8] c"c = %ld\0A\00", align 1 + +define dso_local i8 @d(i64 %h) local_unnamed_addr { +entry: + ret i8 undef +} + +declare dso_local i32 @printf(i8* nocapture readonly, ...) local_unnamed_addr + +define dso_local i32 @main() local_unnamed_addr { +entry: + %bf.load = load i64, i64* bitcast ({ [3 x i8], i8, i8, i8, i8, i8 }* @b to i64*), align 8 + %0 = lshr i64 %bf.load, 30 + %sext3 = shl nuw nsw i64 %0, 16 + %sext = trunc i64 %sext3 to i32 + %conv.i = ashr exact i32 %sext, 16 + %conv.i.i = zext i32 %conv.i to i64 +; CHECK: // %bb.0: +; CHECK: sbfx x{{[0-9]+}}, x{{[0-9]+}}, #{{[0-9]+}}, #{{[0-9]+}} +; CHECK-NEXT: mov w{{[0-9]+}}, w{{[0-9]+}} + store i64 %conv.i.i, i64* @c, align 8 + %call.i.i = tail call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0), i64 %conv.i.i) + %call4.i = tail call i8 bitcast (i8 (i64)* @d to i8 (i32, i32)*)(i32 0, i32 %conv.i) + ret i32 0 +}