Index: llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h =================================================================== --- llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ llvm/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,256), so we can use the @ABS8 + /// symbol modifier. + MO_ABS8, }; enum : uint64_t { Index: llvm/lib/Target/X86/X86MCInstLower.cpp =================================================================== --- llvm/lib/Target/X86/X86MCInstLower.cpp +++ llvm/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_ABS8; break; case X86II::MO_PIC_BASE_OFFSET: case X86II::MO_DARWIN_NONLAZY_PIC_BASE: Expr = MCSymbolRefExpr::create(Sym, Ctx); Index: llvm/lib/Target/X86/X86Subtarget.cpp =================================================================== --- llvm/lib/Target/X86/X86Subtarget.cpp +++ llvm/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,15 @@ 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. + if (CR->getUnsignedMax().ult(256)) + return X86II::MO_ABS8; + else + return X86II::MO_NO_FLAG; + } + } if (TM.shouldAssumeDSOLocal(M, GV)) return classifyLocalReference(GV); Index: llvm/test/CodeGen/X86/absolute-bit-mask.ll =================================================================== --- llvm/test/CodeGen/X86/absolute-bit-mask.ll +++ llvm/test/CodeGen/X86/absolute-bit-mask.ll @@ -12,7 +12,7 @@ define void @foo8(i8* %ptr) { %load = load i8, i8* %ptr - ; CHECK: testb $bit_mask8, (%rdi) + ; CHECK: testb $bit_mask8@ABS8, (%rdi) %and = and i8 %load, ptrtoint (i8* @bit_mask8 to i8) %icmp = icmp eq i8 %and, 0 br i1 %icmp, label %t, label %f Index: llvm/test/CodeGen/X86/absolute-constant.ll =================================================================== --- llvm/test/CodeGen/X86/absolute-constant.ll +++ llvm/test/CodeGen/X86/absolute-constant.ll @@ -10,7 +10,7 @@ entry: %0 = load i8, i8* %x, align 1 %conv = sext i8 %0 to i32 - ; CHECK: testb $foo, (%rdi) + ; CHECK: testb $foo@ABS8, (%rdi) %and = and i32 %conv, sext (i8 ptrtoint (i8* @foo to i8) to i32) %tobool = icmp eq i32 %and, 0 br i1 %tobool, label %if.end, label %if.then Index: llvm/test/CodeGen/X86/absolute-rotate.ll =================================================================== --- llvm/test/CodeGen/X86/absolute-rotate.ll +++ llvm/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