[llvm-commits] [patch] Teach SimplifyCFG about magic pointer constants

Dan Gohman gohman at apple.com
Fri Feb 5 13:23:09 PST 2010


Hi Jakob,

Looks good to me. Just one comment:

+  // IntToPtr const int.
+  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+    if (CE->getOpcode() == Instruction::IntToPtr)
+      if (ConstantInt *CI = dyn_cast<ConstantInt>(CE->getOperand(0))) {
+        // The constant is very likely to have the right type already.
+        if (CI->getType() == PtrTy)
+          return CI;
+        else
+          return ConstantInt::get(PtrTy, CI->getZExtValue());

getZExtValue() fails if the integer is wider than 64 bits. To be
more general, you can use something like

ConstantExpr::getIntegerCast(CI, PtrTy, /*isSigned=*/false)

to convert the constant to the appropriate type.

+      }
+  return 0;

Dan

On Feb 5, 2010, at 12:12 PM, Jakob Stoklund Olesen wrote:

> 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 and benefits from this.
> 
> <magicptr.patch>_______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list