Teach SimplifyCFG about magic pointer constants.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 5 Feb 2010 22:03:18 +0000 (22:03 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 5 Feb 2010 22:03:18 +0000 (22:03 +0000)
commit58e9ee85fda5083e2eea987917e8eab6ba31fe5e
tree542d47cbb2c02e5971df3c80b71b290118bd7877
parent00cb3fe786855ce6545234bc3430223eb9272206
Teach SimplifyCFG about magic pointer constants.

Weird code sometimes uses pointer constants other than null. This patch
teaches SimplifyCFG to build switch instructions in those cases.

Code like this:

void f(const char *x) {
  if (!x)
    puts("null");
  else if ((uintptr_t)x == 1)
    puts("one");
  else if (x == (char*)2 || x == (char*)3)
    puts("two");
  else if ((intptr_t)x == 4)
    puts("four");
  else
    puts(x);
}

Now becomes a switch:

define void @f(i8* %x) nounwind ssp {
entry:
  %magicptr23 = ptrtoint i8* %x to i64            ; <i64> [#uses=1]
  switch i64 %magicptr23, label %if.else16 [
    i64 0, label %if.then
    i64 1, label %if.then2
    i64 2, label %if.then9
    i64 3, label %if.then9
    i64 4, label %if.then14
  ]

Note that LLVM's own DenseMap uses magic pointers.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95439 91177308-0d34-0410-b5e6-96231b3b80d8
include/llvm/Transforms/Utils/Local.h
lib/Transforms/Scalar/SimplifyCFGPass.cpp
lib/Transforms/Utils/SimplifyCFG.cpp
test/Transforms/SimplifyCFG/MagicPointer.ll [new file with mode: 0644]