Index: lib/CodeGen/MIRParser/MILexer.h =================================================================== --- lib/CodeGen/MIRParser/MILexer.h +++ lib/CodeGen/MIRParser/MILexer.h @@ -113,6 +113,7 @@ kw_successors, kw_floatpred, kw_intpred, + kw_unknown_size, // Named metadata keywords md_tbaa, Index: lib/CodeGen/MIRParser/MILexer.cpp =================================================================== --- lib/CodeGen/MIRParser/MILexer.cpp +++ lib/CodeGen/MIRParser/MILexer.cpp @@ -245,6 +245,7 @@ .Case("successors", MIToken::kw_successors) .Case("floatpred", MIToken::kw_floatpred) .Case("intpred", MIToken::kw_intpred) + .Case("unknown-size", MIToken::kw_unknown_size) .Default(MIToken::Identifier); } Index: lib/CodeGen/MIRParser/MIParser.cpp =================================================================== --- lib/CodeGen/MIRParser/MIParser.cpp +++ lib/CodeGen/MIRParser/MIParser.cpp @@ -24,6 +24,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" +#include "llvm/Analysis/MemoryLocation.h" #include "llvm/AsmParser/Parser.h" #include "llvm/AsmParser/SlotMapping.h" #include "llvm/CodeGen/MIRPrinter.h" @@ -2423,7 +2424,7 @@ return false; } - return error("expected an atomic scope, ordering or a size integer literal"); + return error("expected an atomic scope, ordering or a size specification"); } bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) { @@ -2462,11 +2463,17 @@ if (parseOptionalAtomicOrdering(FailureOrder)) return true; - if (Token.isNot(MIToken::IntegerLiteral)) - return error("expected the size integer literal after memory operation"); + if (Token.isNot(MIToken::IntegerLiteral) && + Token.isNot(MIToken::kw_unknown_size)) + return error("expected the size integer literal or 'unknown-size' after " + "memory operation"); uint64_t Size; - if (getUint64(Size)) - return true; + if (Token.is(MIToken::IntegerLiteral)) { + if (getUint64(Size)) + return true; + } else if (Token.is(MIToken::kw_unknown_size)) { + Size = MemoryLocation::UnknownSize; + } lex(); MachinePointerInfo Ptr = MachinePointerInfo(); @@ -2483,7 +2490,7 @@ if (parseMachinePointerInfo(Ptr)) return true; } - unsigned BaseAlignment = Size; + unsigned BaseAlignment = (Size != MemoryLocation::UnknownSize ? Size : 1); AAMDNodes AAInfo; MDNode *Range = nullptr; while (consumeIfPresent(MIToken::comma)) { Index: lib/CodeGen/MachineInstr.cpp =================================================================== --- lib/CodeGen/MachineInstr.cpp +++ lib/CodeGen/MachineInstr.cpp @@ -1050,10 +1050,13 @@ int64_t OffsetA = MMOa->getOffset(); int64_t OffsetB = MMOb->getOffset(); - int64_t MinOffset = std::min(OffsetA, OffsetB); - int64_t WidthA = MMOa->getSize(); - int64_t WidthB = MMOb->getSize(); + + uint64_t WidthA = MMOa->getSize(); + uint64_t WidthB = MMOb->getSize(); + bool KnownWidthA = WidthA != MemoryLocation::UnknownSize; + bool KnownWidthB = WidthB != MemoryLocation::UnknownSize; + const Value *ValA = MMOa->getValue(); const Value *ValB = MMOb->getValue(); bool SameVal = (ValA && ValB && (ValA == ValB)); @@ -1069,6 +1072,8 @@ } if (SameVal) { + if (!KnownWidthA || !KnownWidthB) + return true; int64_t MaxOffset = std::max(OffsetA, OffsetB); int64_t LowWidth = (MinOffset == OffsetA) ? WidthA : WidthB; return (MinOffset + LowWidth > MaxOffset); @@ -1083,13 +1088,15 @@ assert((OffsetA >= 0) && "Negative MachineMemOperand offset"); assert((OffsetB >= 0) && "Negative MachineMemOperand offset"); - int64_t Overlapa = WidthA + OffsetA - MinOffset; - int64_t Overlapb = WidthB + OffsetB - MinOffset; + int64_t OverlapA = KnownWidthA ? WidthA + OffsetA - MinOffset + : MemoryLocation::UnknownSize; + int64_t OverlapB = KnownWidthB ? WidthB + OffsetB - MinOffset + : MemoryLocation::UnknownSize; AliasResult AAResult = AA->alias( - MemoryLocation(ValA, Overlapa, + MemoryLocation(ValA, OverlapA, UseTBAA ? MMOa->getAAInfo() : AAMDNodes()), - MemoryLocation(ValB, Overlapb, + MemoryLocation(ValB, OverlapB, UseTBAA ? MMOb->getAAInfo() : AAMDNodes())); return (AAResult != NoAlias); Index: lib/CodeGen/MachineOperand.cpp =================================================================== --- lib/CodeGen/MachineOperand.cpp +++ lib/CodeGen/MachineOperand.cpp @@ -14,6 +14,7 @@ #include "llvm/CodeGen/MachineOperand.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/Loads.h" +#include "llvm/Analysis/MemoryLocation.h" #include "llvm/CodeGen/MIRPrinter.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" @@ -1078,7 +1079,11 @@ if (getFailureOrdering() != AtomicOrdering::NotAtomic) OS << toIRString(getFailureOrdering()) << ' '; - OS << getSize(); + if (getSize() == MemoryLocation::UnknownSize) + OS << "unknown-size"; + else + OS << getSize(); + if (const Value *Val = getValue()) { OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into "); printIRValueReference(OS, *Val, MST); Index: lib/CodeGen/MachinePipeliner.cpp =================================================================== --- lib/CodeGen/MachinePipeliner.cpp +++ lib/CodeGen/MachinePipeliner.cpp @@ -3189,11 +3189,11 @@ unsigned Delta; if (Num != UINT_MAX && computeDelta(OldMI, Delta)) { int64_t AdjOffset = Delta * Num; - NewMemRefs[Refs++] = - MF.getMachineMemOperand(MMO, AdjOffset, MMO->getSize()); + NewMemRefs[Refs++] = MF.getMachineMemOperand(MMO, AdjOffset, + MMO->getSize()); } else { - NewMI.dropMemRefs(); - return; + NewMemRefs[Refs++] = MF.getMachineMemOperand(MMO, 0, + MemoryLocation::UnknownSize); } } NewMI.setMemRefs(NewMemRefs, NewMemRefs + NumRefs); Index: test/CodeGen/MIR/X86/expected-size-integer-after-memory-operation.mir =================================================================== --- test/CodeGen/MIR/X86/expected-size-integer-after-memory-operation.mir +++ test/CodeGen/MIR/X86/expected-size-integer-after-memory-operation.mir @@ -17,7 +17,7 @@ body: | bb.0.entry: liveins: $rdi - ; CHECK: [[@LINE+1]]:53: expected an atomic scope, ordering or a size integer literal + ; CHECK: [[@LINE+1]]:53: expected an atomic scope, ordering or a size specification $eax = MOV32rm killed $rdi, 1, _, 0, _ :: (load from %ir.a) RETQ $eax ... Index: test/CodeGen/MIR/X86/expected-size-integer-after-memory-operation2.mir =================================================================== --- /dev/null +++ test/CodeGen/MIR/X86/expected-size-integer-after-memory-operation2.mir @@ -0,0 +1,24 @@ +# RUN: not llc -march=x86-64 -run-pass none -o /dev/null %s 2>&1 | FileCheck %s + +--- | + + define i32 @test(i32* %a) { + entry: + %b = load i32, i32* %a + ret i32 %b + } + +... +--- +name: test +tracksRegLiveness: true +liveins: + - { reg: '$rdi' } +body: | + bb.0.entry: + liveins: $rdi + ; CHECK: [[@LINE+1]]:53: expected the size integer literal or 'unknown-size' after memory operation + $eax = MOV32rm killed $rdi, 1, _, 0, _ :: (load . from %ir.a) + RETQ $eax +... + Index: test/CodeGen/MIR/X86/memory-operands.mir =================================================================== --- test/CodeGen/MIR/X86/memory-operands.mir +++ test/CodeGen/MIR/X86/memory-operands.mir @@ -189,6 +189,8 @@ define void @dummy0() { ret void } define void @dummy1() { ret void } + define void @dummy2() { ret void } + define void @dummy3() { ret void } ... --- name: test @@ -532,5 +534,30 @@ bb.0: $rax = MOV64rm $rsp, 1, _, 0, _ :: (load 8 from %stack.0) RETQ $rax - +... +--- +# Test parsing of unknown size in machine memory operands without alignment. +# CHECK-LABEL: name: dummy2 +# CHECK: $rax = MOV64rm $rsp, 1, $noreg, 0, $noreg :: (load unknown-size from %stack.0, align 1) +name: dummy2 +tracksRegLiveness: true +stack: + - { id: 0, size: 4, alignment: 4 } +body: | + bb.0: + $rax = MOV64rm $rsp, 1, _, 0, _ :: (load unknown-size from %stack.0) + RETQ $rax +... +--- +# Test parsing of unknown size in machine memory operands with alignment. +# CHECK-LABEL: name: dummy3 +# CHECK: $rax = MOV64rm $rsp, 1, $noreg, 0, $noreg :: (load unknown-size from %stack.0, align 4) +name: dummy3 +tracksRegLiveness: true +stack: + - { id: 0, size: 4, alignment: 4 } +body: | + bb.0: + $rax = MOV64rm $rsp, 1, _, 0, _ :: (load unknown-size from %stack.0, align 4) + RETQ $rax ...