Index: llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h =================================================================== --- llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -212,7 +212,12 @@ /// 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 { Index: llvm/trunk/lib/Target/X86/X86MCInstLower.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86MCInstLower.cpp +++ llvm/trunk/lib/Target/X86/X86MCInstLower.cpp @@ -215,6 +215,7 @@ 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); Index: llvm/trunk/lib/Target/X86/X86Subtarget.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp +++ llvm/trunk/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 @@ 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); Index: llvm/trunk/test/CodeGen/X86/absolute-rotate.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/absolute-rotate.ll +++ llvm/trunk/test/CodeGen/X86/absolute-rotate.ll @@ -11,7 +11,7 @@ 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 @@ ret void } -!0 = !{i64 0, i64 256} +!0 = !{i64 0, i64 128}