[MemLoc] Fix a bug causing any use of invariant.end to crash in LICM
authorPhilip Reames <listmail@philipreames.com>
Thu, 16 Aug 2018 20:48:55 +0000 (20:48 +0000)
committerPhilip Reames <listmail@philipreames.com>
Thu, 16 Aug 2018 20:48:55 +0000 (20:48 +0000)
The fix is fairly simple, but is says something unpleasant about the usage and testing of invariant.start/end scopes that this went undetected.  To put this in perspective, *any* invariant.end in a loop flowing through LICM crashed.  I haven't bothered to figure out just how far back this goes, but it's not caused by any of the recent changes.  We're probably talking months if not years.

llvm-svn: 339936

llvm/lib/Analysis/MemoryLocation.cpp
llvm/test/Transforms/LICM/invariant.start.ll

index 55924db..43cebcd 100644 (file)
@@ -137,6 +137,10 @@ MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS,
           Arg, cast<ConstantInt>(II->getArgOperand(0))->getZExtValue(), AATags);
 
     case Intrinsic::invariant_end:
+      // The first argument to an invariant.end is a "descriptor" type (e.g. a
+      // pointer to a empty struct) which is never actually dereferenced.
+      if (ArgIdx == 0)
+        return MemoryLocation(Arg, 0, AATags);
       assert(ArgIdx == 2 && "Invalid argument index");
       return MemoryLocation(
           Arg, cast<ConstantInt>(II->getArgOperand(1))->getZExtValue(), AATags);
index 6c587ac..ff17bd0 100644 (file)
@@ -101,9 +101,7 @@ loop:
   store i32 0, i32* %ptr
   %scope = call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
   %val = load i32, i32* %ptr
-;;  NOTE: despite being correct syntax, uncommenting this line causes
-;;  a crash in the optimizer.  FIXME
-;;  call void @llvm.invariant.end.p0i32({}* %scope, i64 4, i32* %ptr)
+  call void @llvm.invariant.end.p0i32({}* %scope, i64 4, i32* %ptr)
   %x.inc = add i32 %x, %val
   br label %loop
 }