From e60585b09172801e03614cc562a3f6aa2d67ee89 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 2 Feb 2017 00:32:03 +0000 Subject: [PATCH] X86: Produce @ABS8 symbol modifiers for absolute symbols in range [0,128). Differential Revision: https://reviews.llvm.org/D28689 llvm-svn: 293844 --- lib/Target/X86/MCTargetDesc/X86BaseInfo.h | 7 ++++++- lib/Target/X86/X86MCInstLower.cpp | 1 + lib/Target/X86/X86Subtarget.cpp | 14 ++++++++++++-- test/CodeGen/X86/absolute-rotate.ll | 4 ++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index aab552547fa..d8953da4abb 100644 --- a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -212,7 +212,12 @@ namespace X86II { /// the offset from beginning of section. /// /// This is the TLS offset for the COFF/Windows TLS mechanism. - MO_SECREL + MO_SECREL, + + /// MO_ABS8 - On a symbol operand this indicates that the symbol is known + /// to be an absolute symbol in range [0,128), so we can use the @ABS8 + /// symbol modifier. + MO_ABS8, }; enum : uint64_t { diff --git a/lib/Target/X86/X86MCInstLower.cpp b/lib/Target/X86/X86MCInstLower.cpp index c7cc1a08237..fd4626c494e 100644 --- a/lib/Target/X86/X86MCInstLower.cpp +++ b/lib/Target/X86/X86MCInstLower.cpp @@ -215,6 +215,7 @@ MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO, case X86II::MO_GOT: RefKind = MCSymbolRefExpr::VK_GOT; break; case X86II::MO_GOTOFF: RefKind = MCSymbolRefExpr::VK_GOTOFF; break; case X86II::MO_PLT: RefKind = MCSymbolRefExpr::VK_PLT; break; + case X86II::MO_ABS8: RefKind = MCSymbolRefExpr::VK_X86_ABS8; break; case X86II::MO_PIC_BASE_OFFSET: case X86II::MO_DARWIN_NONLAZY_PIC_BASE: Expr = MCSymbolRefExpr::create(Sym, Ctx); diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp index 586bb7bd7b1..69ed9256248 100644 --- a/lib/Target/X86/X86Subtarget.cpp +++ b/lib/Target/X86/X86Subtarget.cpp @@ -15,6 +15,7 @@ #include "X86InstrInfo.h" #include "X86TargetMachine.h" #include "llvm/IR/Attributes.h" +#include "llvm/IR/ConstantRange.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalValue.h" #include "llvm/Support/CommandLine.h" @@ -93,8 +94,17 @@ unsigned char X86Subtarget::classifyGlobalReference(const GlobalValue *GV, return X86II::MO_NO_FLAG; // Absolute symbols can be referenced directly. - if (GV && GV->isAbsoluteSymbolRef()) - return X86II::MO_NO_FLAG; + if (GV) { + if (Optional CR = GV->getAbsoluteSymbolRange()) { + // See if we can use the 8-bit immediate form. Note that some instructions + // will sign extend the immediate operand, so to be conservative we only + // accept the range [0,128). + if (CR->getUnsignedMax().ult(128)) + return X86II::MO_ABS8; + else + return X86II::MO_NO_FLAG; + } + } if (TM.shouldAssumeDSOLocal(M, GV)) return classifyLocalReference(GV); diff --git a/test/CodeGen/X86/absolute-rotate.ll b/test/CodeGen/X86/absolute-rotate.ll index c0ecb82adc2..6240e8d3f76 100644 --- a/test/CodeGen/X86/absolute-rotate.ll +++ b/test/CodeGen/X86/absolute-rotate.ll @@ -11,7 +11,7 @@ declare void @f() define void @foo(i64 %val) { %shr = lshr i64 %val, zext (i8 ptrtoint (i8* @align to i8) to i64) %shl = shl i64 %val, zext (i8 sub (i8 64, i8 ptrtoint (i8* @align to i8)) to i64) - ; CHECK: rorq $align, %rdi + ; CHECK: rorq $align@ABS8, %rdi %ror = or i64 %shr, %shl %cmp = icmp ult i64 %ror, 109 br i1 %cmp, label %t, label %f @@ -24,4 +24,4 @@ f: ret void } -!0 = !{i64 0, i64 256} +!0 = !{i64 0, i64 128}