Adding an intrinsic that requires a constant parameter

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Adding an intrinsic that requires a constant parameter

Justin Holewinski-2
My understanding of intrinsics in LLVM is that an optimization pass cannot touch an intrinsic unless it (1) is specifically programmed to have knowledge of the intrinsic, or (2) uses only declared properties of the intrinsic, like IntrNoMem.  So, for example, a pass may move an unknown intrinsic around memory ops if its defined IntrNoMem, but it cannot hoist constants for arbitrary intrinsics.  Is this correct?  I can't find this codified anywhere in the documentation.

The context for this question is adding an intrinsic that requires a constant parameter.  There is no way to define this property in the tablegen description currently.  I want to verify that if I add such an intrinsic, it would be illegal for any existing optimization pass to hoist the constant parameter.  For example, if I add a target intrinsic llvm.foo that takes two parameters: i32 and i1, where the i1 parameter must be a constant (same as llvm.cttz), I want to verify that the following optimization is illegal without having to change any LLVM passes:

Input:

define i32 @f0(i32 %a, i1 %pred) {
  br i1 %pred, label %first, label %second
first:
  %r0 = tail call i32 @llvm.foo.i32(i32 %a, i1 true)
  br label %end
second:
  %r1 = tail call i32 @llvm.foo.i32(i32 %a, i1 false)
  br label %end
end:
  %r = phi i32 [%r0, %first], [%r1, %second]
  ret i32 %r
}

Output:

define i32 @f1(i32 %a, i1 %pred) {
  %r = tail call i32 @llvm.foo.i32(i32 %a, i1 %pred)
  ret i32 %r
}

--

Thanks,

Justin Holewinski

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Adding an intrinsic that requires a constant parameter

Rafael Espíndola
The shufflevector instruction has this property on the mask, not sure
if the same implementation would work for an intrinsic.

On 1 May 2014 08:10, Justin Holewinski <[hidden email]> wrote:

> My understanding of intrinsics in LLVM is that an optimization pass cannot
> touch an intrinsic unless it (1) is specifically programmed to have
> knowledge of the intrinsic, or (2) uses only declared properties of the
> intrinsic, like IntrNoMem.  So, for example, a pass may move an unknown
> intrinsic around memory ops if its defined IntrNoMem, but it cannot hoist
> constants for arbitrary intrinsics.  Is this correct?  I can't find this
> codified anywhere in the documentation.
>
> The context for this question is adding an intrinsic that requires a
> constant parameter.  There is no way to define this property in the tablegen
> description currently.  I want to verify that if I add such an intrinsic, it
> would be illegal for any existing optimization pass to hoist the constant
> parameter.  For example, if I add a target intrinsic llvm.foo that takes two
> parameters: i32 and i1, where the i1 parameter must be a constant (same as
> llvm.cttz), I want to verify that the following optimization is illegal
> without having to change any LLVM passes:
>
> Input:
>
> define i32 @f0(i32 %a, i1 %pred) {
>   br i1 %pred, label %first, label %second
> first:
>   %r0 = tail call i32 @llvm.foo.i32(i32 %a, i1 true)
>   br label %end
> second:
>   %r1 = tail call i32 @llvm.foo.i32(i32 %a, i1 false)
>   br label %end
> end:
>   %r = phi i32 [%r0, %first], [%r1, %second]
>   ret i32 %r
> }
>
> Output:
>
> define i32 @f1(i32 %a, i1 %pred) {
>   %r = tail call i32 @llvm.foo.i32(i32 %a, i1 %pred)
>   ret i32 %r
> }
>
> --
>
> Thanks,
>
> Justin Holewinski
>
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Adding an intrinsic that requires a constant parameter

Reid Kleckner-2
In reply to this post by Justin Holewinski-2
Looks like LLVM won't tolerate that optimization.  There are a bunch of intrinsics that require constant args.  The verifier checks that they are constant args in Verifier::visitIntrinsicFunctionCall(), and this fails verification:

define void @myprefetch(i8* nocapture %p, i32 %rw) {
  tail call void @llvm.prefetch(i8* %p, i32 %rw, i32 3, i32 1)
  ret void
}

We should probably note which args have to be constant in the .td file so passes can avoid breaking these intrinsics in exactly this way.


On Thu, May 1, 2014 at 5:10 AM, Justin Holewinski <[hidden email]> wrote:
My understanding of intrinsics in LLVM is that an optimization pass cannot touch an intrinsic unless it (1) is specifically programmed to have knowledge of the intrinsic, or (2) uses only declared properties of the intrinsic, like IntrNoMem.  So, for example, a pass may move an unknown intrinsic around memory ops if its defined IntrNoMem, but it cannot hoist constants for arbitrary intrinsics.  Is this correct?  I can't find this codified anywhere in the documentation.

The context for this question is adding an intrinsic that requires a constant parameter.  There is no way to define this property in the tablegen description currently.  I want to verify that if I add such an intrinsic, it would be illegal for any existing optimization pass to hoist the constant parameter.  For example, if I add a target intrinsic llvm.foo that takes two parameters: i32 and i1, where the i1 parameter must be a constant (same as llvm.cttz), I want to verify that the following optimization is illegal without having to change any LLVM passes:

Input:

define i32 @f0(i32 %a, i1 %pred) {
  br i1 %pred, label %first, label %second
first:
  %r0 = tail call i32 @llvm.foo.i32(i32 %a, i1 true)
  br label %end
second:
  %r1 = tail call i32 @llvm.foo.i32(i32 %a, i1 false)
  br label %end
end:
  %r = phi i32 [%r0, %first], [%r1, %second]
  ret i32 %r
}

Output:

define i32 @f1(i32 %a, i1 %pred) {
  %r = tail call i32 @llvm.foo.i32(i32 %a, i1 %pred)
  ret i32 %r
}

--

Thanks,

Justin Holewinski

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev



_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Adding an intrinsic that requires a constant parameter

Justin Holewinski-2
Right, that's where I'm going with this.  Many intrinsics already make use of constant-only parameters, but I'm wondering if there are any documented requirements for passes that make sure this works, or if we have just been getting lucky with the current intrinsics.


On Thu, May 1, 2014 at 11:44 AM, Reid Kleckner <[hidden email]> wrote:
Looks like LLVM won't tolerate that optimization.  There are a bunch of intrinsics that require constant args.  The verifier checks that they are constant args in Verifier::visitIntrinsicFunctionCall(), and this fails verification:

define void @myprefetch(i8* nocapture %p, i32 %rw) {
  tail call void @llvm.prefetch(i8* %p, i32 %rw, i32 3, i32 1)
  ret void
}

We should probably note which args have to be constant in the .td file so passes can avoid breaking these intrinsics in exactly this way.


On Thu, May 1, 2014 at 5:10 AM, Justin Holewinski <[hidden email]> wrote:
My understanding of intrinsics in LLVM is that an optimization pass cannot touch an intrinsic unless it (1) is specifically programmed to have knowledge of the intrinsic, or (2) uses only declared properties of the intrinsic, like IntrNoMem.  So, for example, a pass may move an unknown intrinsic around memory ops if its defined IntrNoMem, but it cannot hoist constants for arbitrary intrinsics.  Is this correct?  I can't find this codified anywhere in the documentation.

The context for this question is adding an intrinsic that requires a constant parameter.  There is no way to define this property in the tablegen description currently.  I want to verify that if I add such an intrinsic, it would be illegal for any existing optimization pass to hoist the constant parameter.  For example, if I add a target intrinsic llvm.foo that takes two parameters: i32 and i1, where the i1 parameter must be a constant (same as llvm.cttz), I want to verify that the following optimization is illegal without having to change any LLVM passes:

Input:

define i32 @f0(i32 %a, i1 %pred) {
  br i1 %pred, label %first, label %second
first:
  %r0 = tail call i32 @llvm.foo.i32(i32 %a, i1 true)
  br label %end
second:
  %r1 = tail call i32 @llvm.foo.i32(i32 %a, i1 false)
  br label %end
end:
  %r = phi i32 [%r0, %first], [%r1, %second]
  ret i32 %r
}

Output:

define i32 @f1(i32 %a, i1 %pred) {
  %r = tail call i32 @llvm.foo.i32(i32 %a, i1 %pred)
  ret i32 %r
}

--

Thanks,

Justin Holewinski

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev





--

Thanks,

Justin Holewinski

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev