Dominik Montada via llvm-dev
2020-Mar-12 16:46 UTC
[llvm-dev] Correct modelling of instructions with types smaller than the register class
Hi Quentin, thank you for the reply! I have a couple more questions that came up when I tried to implement this today. I hope you can help me out with this again! Am 09.03.20 um 23:31 schrieb Quentin Colombet:> I would expect that you could create a register class and register > bank for the special register. That way you have something to map to > when you do register bank select. > The register class could be "not allocatable” (see CCR in AArch64 for > instance). > Note, that if that class is unallocable, you’ll have to manage > manually any overlapping that could arise. > E.g., > s32 ..., s1 carry1 = G_UADDO > s32 ..., s1 carry2 = G_UADDO > s32 extended_carry1 = zext s1 carry1 <— carry1 will be destroyed by > the second G_UADDO, you’ll have to fix the schedule or copy the value > manually. > s32 extended_carry2 = zext s1 carry2 > icmp s32 extended_carry1, extended_carry2So before instruction selection we would need to check if there are any overlaps and if so try to fix them if possible or abort compilation if that is not possible?> > Then when you do instruction selection, just map the register to the > physical register. (You may want to do the fix-ups I mentioned here.)What exactly do you mean by "map the register to the physical register"? Do you mean that I should just emit a COPY from/to this physical register and constrain the virtual register to the non-allocatable register class? Because this actually gives me an assertion that the register class must be allocatable. Or do you mean to use the physical register in the target instruction instead of the virtual one (i.e. drop the usage of the virtual register and replace it with the physical register)? The target instruction uses the physical register implicitly by the way. I also tried to take a look at how AArch64 implements G_UADDO/G_UADDE but it doesn't seem to fully implement selection for those? Maybe I just didn't read the code properly...> > I would expect that you could create a register class and register > bank for the special register. That way you have something to map to > when you do register bank select. >I looked at the CC regbank of AArch64, however I didn't see any mappings using it in RegBankInfo. Is that something that AArch64 simply hasn't implemented or is there something going on that I'm not seeing. I mean, what is the point to have a register bank when it is not used during regbankselect? I would at least expect that for example G_UADDO would use this register bank for the s1 carry out.> > Generally speaking, I think you would need a copy (or zext/sext) to > move the value in general purpose land (like in my example with zext). > If you don’t have such use, the copy wouldn’t be emitted and there is > nothing to do. > > To be honest, I think the situation is complicated today because GISel > lack the fix-up that I mentioned. I am actually surprised that didn’t > come up as an issue yet (x86 is full of these flags). Going forward, I > think it should just come with the framework: you assign a physreg > selection time, GISel copies it around/reschedule appropriately to > preserve the value. There’s a lot of wishful thinking here x). > > Cheers, > -Quentin >Best regards, Dominik -- ---------------------------------------------------------------------- Dominik Montada Email: dominik.montada at hightec-rt.com HighTec EDV-Systeme GmbH Phone: +49 681 92613 19 Europaallee 19 Fax: +49-681-92613-26 D-66113 Saarbrücken WWW: http://www.hightec-rt.com Managing Director: Vera Strothmann Register Court: Saarbrücken, HRB 10445, VAT ID: DE 138344222 This e-mail may contain confidential and/or privileged information. If you are not the intended recipient please notify the sender immediately and destroy this e-mail. Any unauthorised copying, disclosure or distribution of the material in this e-mail is strictly forbidden. --- -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 5409 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200312/60c2d4ac/attachment-0001.bin>
Quentin Colombet via llvm-dev
2020-Mar-13 23:17 UTC
[llvm-dev] Correct modelling of instructions with types smaller than the register class
Hi Dominik,> On Mar 12, 2020, at 9:46 AM, Dominik Montada <dominik.montada at hightec-rt.com> wrote: > > Hi Quentin, > > thank you for the reply! I have a couple more questions that came up when I tried to implement this today. I hope you can help me out with this again! > > Am 09.03.20 um 23:31 schrieb Quentin Colombet: >> I would expect that you could create a register class and register bank for the special register. That way you have something to map to when you do register bank select. >> The register class could be "not allocatable” (see CCR in AArch64 for instance). >> Note, that if that class is unallocable, you’ll have to manage manually any overlapping that could arise. >> E.g., >> s32 ..., s1 carry1 = G_UADDO >> s32 ..., s1 carry2 = G_UADDO >> s32 extended_carry1 = zext s1 carry1 <— carry1 will be destroyed by the second G_UADDO, you’ll have to fix the schedule or copy the value manually. >> s32 extended_carry2 = zext s1 carry2 >> icmp s32 extended_carry1, extended_carry2 > So before instruction selection we would need to check if there are any overlaps and if so try to fix them if possible or abort compilation if that is not possible?You could do it after (or during selection maybe), but yeah, you’ll need to fix that eventually. For now, I guess you could just abort if you run in that situation.>> >> Then when you do instruction selection, just map the register to the physical register. (You may want to do the fix-ups I mentioned here.) > > What exactly do you mean by "map the register to the physical register"? Do you mean that I should just emit a COPY from/to this physical register and constrain the virtual register to the non-allocatable register class? > Because this actually gives me an assertion that the register class must be allocatable. Or do you mean to use the physical register in the target instruction instead of the virtual one (i.e. drop the usage of the virtual register and replace it with the physical register)?The latter: replace the virtual register with the physical register directly. That way the only copies left would be to/from general purpose registers, if any. The problem with doing that is that you have to check for potential overlaps manually. Another option would be to go with the special register class we already talked about, make it allocatable, with just one register. That way if there are overlapping ones, regalloc will take care of them (probably with "ran out of register” if you don’t do anything.)> The target instruction uses the physical register implicitly by the way. > > I also tried to take a look at how AArch64 implements G_UADDO/G_UADDE but it doesn't seem to fully implement selection for those? Maybe I just didn't read the code properly...That could be right, it’s been a while since I looked at the code there.> >> >> I would expect that you could create a register class and register bank for the special register. That way you have something to map to when you do register bank select. >> > I looked at the CC regbank of AArch64, however I didn't see any mappings using it in RegBankInfo.I see that in AArch64RegisterBanks.td: /// Conditional register: NZCV. def CCRegBank : RegisterBank<"CC", [CCR]>; But that’s about it.> Is that something that AArch64 simply hasn't implemented or is there something going on that I'm not seeing. I mean, what is the point to have a register bank when it is not used during regbankselect?Good point. Again, it’s been a while I haven’t looked at AArch64, so I don’t really know the status here. @Tim, @Amara?> I would at least expect that for example G_UADDO would use this register bank for the s1 carry out.That would have been my expectation as well.>> >> Generally speaking, I think you would need a copy (or zext/sext) to move the value in general purpose land (like in my example with zext). If you don’t have such use, the copy wouldn’t be emitted and there is nothing to do. >> >> To be honest, I think the situation is complicated today because GISel lack the fix-up that I mentioned. I am actually surprised that didn’t come up as an issue yet (x86 is full of these flags). Going forward, I think it should just come with the framework: you assign a physreg selection time, GISel copies it around/reschedule appropriately to preserve the value. There’s a lot of wishful thinking here x). >> >> Cheers, >> -Quentin >> > Best regards, > > Dominik > > -- > ---------------------------------------------------------------------- > Dominik Montada Email: dominik.montada at hightec-rt.com > HighTec EDV-Systeme GmbH Phone: +49 681 92613 19 > Europaallee 19 Fax: +49-681-92613-26 > D-66113 Saarbrücken WWW: http://www.hightec-rt.com > > Managing Director: Vera Strothmann > Register Court: Saarbrücken, HRB 10445, VAT ID: DE 138344222 > > This e-mail may contain confidential and/or privileged information. If > you are not the intended recipient please notify the sender immediately > and destroy this e-mail. Any unauthorised copying, disclosure or > distribution of the material in this e-mail is strictly forbidden. > --- >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200313/919ef3b6/attachment.html>
Dominik Montada via llvm-dev
2020-Mar-18 11:00 UTC
[llvm-dev] Correct modelling of instructions with types smaller than the register class
Hi Quentin, thanks again for your time. We were now able to implement this and it seems to be working as intended. In the end with went with replacing the virtual registers with the physical one and checking for overlaps. We wanted to let the register allocator handle it initially but ended up having a couple more issues than we expected with that, so we now do this handling ourselves. It would still be very interesting to know why AArch64 isn't doing something similar and how exactly they are solving this issue, but for now I'm happy that we now have a working implementation for our target. Thank you and best regards, Dominik Am 14.03.20 um 00:17 schrieb Quentin Colombet:> Hi Dominik, > >> On Mar 12, 2020, at 9:46 AM, Dominik Montada >> <dominik.montada at hightec-rt.com >> <mailto:dominik.montada at hightec-rt.com>> wrote: >> >> Hi Quentin, >> >> thank you for the reply! I have a couple more questions that came up >> when I tried to implement this today. I hope you can help me out with >> this again! >> >> Am 09.03.20 um 23:31 schrieb Quentin Colombet: >>> I would expect that you could create a register class and register >>> bank for the special register. That way you have something to map to >>> when you do register bank select. >>> The register class could be "not allocatable” (see CCR in AArch64 >>> for instance). >>> Note, that if that class is unallocable, you’ll have to manage >>> manually any overlapping that could arise. >>> E.g., >>> s32 ..., s1 carry1 = G_UADDO >>> s32 ..., s1 carry2 = G_UADDO >>> s32 extended_carry1 = zext s1 carry1 <— carry1 will be destroyed by >>> the second G_UADDO, you’ll have to fix the schedule or copy the >>> value manually. >>> s32 extended_carry2 = zext s1 carry2 >>> icmp s32 extended_carry1, extended_carry2 >> So before instruction selection we would need to check if there are >> any overlaps and if so try to fix them if possible or abort >> compilation if that is not possible? > > You could do it after (or during selection maybe), but yeah, you’ll > need to fix that eventually. For now, I guess you could just abort if > you run in that situation. > >>> >>> Then when you do instruction selection, just map the register to the >>> physical register. (You may want to do the fix-ups I mentioned here.) >> >> What exactly do you mean by "map the register to the physical >> register"? Do you mean that I should just emit a COPY from/to this >> physical register and constrain the virtual register to the >> non-allocatable register class? >> Because this actually gives me an assertion that the register class >> must be allocatable. Or do you mean to use the physical register in >> the target instruction instead of the virtual one (i.e. drop the >> usage of the virtual register and replace it with the physical register)? > > The latter: replace the virtual register with the physical register > directly. That way the only copies left would be to/from general > purpose registers, if any. The problem with doing that is that you > have to check for potential overlaps manually. > > Another option would be to go with the special register class we > already talked about, make it allocatable, with just one register. > That way if there are overlapping ones, regalloc will take care of > them (probably with "ran out of register” if you don’t do anything.) > >> The target instruction uses the physical register implicitly by the way. >> >> I also tried to take a look at how AArch64 implements G_UADDO/G_UADDE >> but it doesn't seem to fully implement selection for those? Maybe I >> just didn't read the code properly... > > That could be right, it’s been a while since I looked at the code there. > >> >>> >>> I would expect that you could create a register class and register >>> bank for the special register. That way you have something to map to >>> when you do register bank select. >>> >> I looked at the CC regbank of AArch64, however I didn't see any >> mappings using it in RegBankInfo. > > I see that in AArch64RegisterBanks.td: > /// Conditional register: NZCV. > def CCRegBank : RegisterBank<"CC", [CCR]>; > > But that’s about it. > >> Is that something that AArch64 simply hasn't implemented or is there >> something going on that I'm not seeing. I mean, what is the point to >> have a register bank when it is not used during regbankselect? > > Good point. Again, it’s been a while I haven’t looked at AArch64, so I > don’t really know the status here. > @Tim, @Amara? > >> I would at least expect that for example G_UADDO would use this >> register bank for the s1 carry out. > > That would have been my expectation as well. > >>> >>> Generally speaking, I think you would need a copy (or zext/sext) to >>> move the value in general purpose land (like in my example with >>> zext). If you don’t have such use, the copy wouldn’t be emitted and >>> there is nothing to do. >>> >>> To be honest, I think the situation is complicated today because >>> GISel lack the fix-up that I mentioned. I am actually surprised that >>> didn’t come up as an issue yet (x86 is full of these flags). Going >>> forward, I think it should just come with the framework: you assign >>> a physreg selection time, GISel copies it around/reschedule >>> appropriately to preserve the value. There’s a lot of wishful >>> thinking here x). >>> >>> Cheers, >>> -Quentin >>> >> Best regards, >> >> Dominik >> >> -- >> ---------------------------------------------------------------------- >> Dominik Montada Email: dominik.montada at hightec-rt.com >> <mailto:dominik.montada at hightec-rt.com> >> HighTec EDV-Systeme GmbH Phone: +49 681 92613 19 >> Europaallee 19 Fax: +49-681-92613-26 >> D-66113 Saarbrücken WWW: http://www.hightec-rt.com >> >> Managing Director: Vera Strothmann >> Register Court: Saarbrücken, HRB 10445, VAT ID: DE 138344222 >> >> This e-mail may contain confidential and/or privileged information. If >> you are not the intended recipient please notify the sender immediately >> and destroy this e-mail. Any unauthorised copying, disclosure or >> distribution of the material in this e-mail is strictly forbidden. >> --- >> >-- ---------------------------------------------------------------------- Dominik Montada Email: dominik.montada at hightec-rt.com HighTec EDV-Systeme GmbH Phone: +49 681 92613 19 Europaallee 19 Fax: +49-681-92613-26 D-66113 Saarbrücken WWW: http://www.hightec-rt.com Managing Director: Vera Strothmann Register Court: Saarbrücken, HRB 10445, VAT ID: DE 138344222 This e-mail may contain confidential and/or privileged information. If you are not the intended recipient please notify the sender immediately and destroy this e-mail. Any unauthorised copying, disclosure or distribution of the material in this e-mail is strictly forbidden. --- -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200318/5e680b4d/attachment-0001.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 5409 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200318/5e680b4d/attachment-0001.bin>
Amara Emerson via llvm-dev
2020-Mar-23 23:56 UTC
[llvm-dev] Correct modelling of instructions with types smaller than the register class
Hi Dominik,> On Mar 12, 2020, at 9:46 AM, Dominik Montada <dominik.montada at hightec-rt.com> wrote: > > Hi Quentin, > > thank you for the reply! I have a couple more questions that came up when I tried to implement this today. I hope you can help me out with this again! > > Am 09.03.20 um 23:31 schrieb Quentin Colombet: >> I would expect that you could create a register class and register bank for the special register. That way you have something to map to when you do register bank select. >> The register class could be "not allocatable” (see CCR in AArch64 for instance). >> Note, that if that class is unallocable, you’ll have to manage manually any overlapping that could arise. >> E.g., >> s32 ..., s1 carry1 = G_UADDO >> s32 ..., s1 carry2 = G_UADDO >> s32 extended_carry1 = zext s1 carry1 <— carry1 will be destroyed by the second G_UADDO, you’ll have to fix the schedule or copy the value manually. >> s32 extended_carry2 = zext s1 carry2 >> icmp s32 extended_carry1, extended_carry2 > So before instruction selection we would need to check if there are any overlaps and if so try to fix them if possible or abort compilation if that is not possible? >> >> Then when you do instruction selection, just map the register to the physical register. (You may want to do the fix-ups I mentioned here.) > > What exactly do you mean by "map the register to the physical register"? Do you mean that I should just emit a COPY from/to this physical register and constrain the virtual register to the non-allocatable register class? Because this actually gives me an assertion that the register class must be allocatable. Or do you mean to use the physical register in the target instruction instead of the virtual one (i.e. drop the usage of the virtual register and replace it with the physical register)? The target instruction uses the physical register implicitly by the way. > > I also tried to take a look at how AArch64 implements G_UADDO/G_UADDE but it doesn't seem to fully implement selection for those? Maybe I just didn't read the code properly…AArch64 doesn’t use the condition register bank, it was added before I joined the project so I’m not entirely sure what the intent was. However, the condition register side effect is something that we explicitly capture in SSA variables by copying every definition into a GPR, for which we do have regbanks for. We do this by using CSET/CSINC instructions on AArch64 which allow us to set a GPR register using the value of the condition register. We do this in every selection of an instruction like G_ICMP or G_UADDO which may write write a flag output. %c1(s1) = G_ICMP eq, %foo, %bar …can be selected into cmp x0, x1 csinc x8, xzr, xzr, eq Which results in the %c1 value being written to the register x8. Because we select in this way, we don’t have any extra side effects to model before selection time. It’s all in SSA. We then have selection patterns that try to optimize sequences like this if we can depending on the context. For G_UADDO, you can see in the selector code that we emit an ADDS flag setting instruction, and then extract the carry flag using a CSET into the carry destination virtual register. Cheers, Amara> >> >> I would expect that you could create a register class and register bank for the special register. That way you have something to map to when you do register bank select. >> > I looked at the CC regbank of AArch64, however I didn't see any mappings using it in RegBankInfo. Is that something that AArch64 simply hasn't implemented or is there something going on that I'm not seeing. I mean, what is the point to have a register bank when it is not used during regbankselect? I would at least expect that for example G_UADDO would use this register bank for the s1 carry out. >> >> Generally speaking, I think you would need a copy (or zext/sext) to move the value in general purpose land (like in my example with zext). If you don’t have such use, the copy wouldn’t be emitted and there is nothing to do. >> >> To be honest, I think the situation is complicated today because GISel lack the fix-up that I mentioned. I am actually surprised that didn’t come up as an issue yet (x86 is full of these flags). Going forward, I think it should just come with the framework: you assign a physreg selection time, GISel copies it around/reschedule appropriately to preserve the value. There’s a lot of wishful thinking here x). >> >> Cheers, >> -Quentin >> > Best regards, > > Dominik > > -- > ---------------------------------------------------------------------- > Dominik Montada Email: dominik.montada at hightec-rt.com > HighTec EDV-Systeme GmbH Phone: +49 681 92613 19 > Europaallee 19 Fax: +49-681-92613-26 > D-66113 Saarbrücken WWW: http://www.hightec-rt.com > > Managing Director: Vera Strothmann > Register Court: Saarbrücken, HRB 10445, VAT ID: DE 138344222 > > This e-mail may contain confidential and/or privileged information. If > you are not the intended recipient please notify the sender immediately > and destroy this e-mail. Any unauthorised copying, disclosure or > distribution of the material in this e-mail is strictly forbidden. > --- >
Dominik Montada via llvm-dev
2020-Mar-24 08:20 UTC
[llvm-dev] Correct modelling of instructions with types smaller than the register class
Hi Amara, thank you for taking the time to reply to this thread, even though our problem has been solved by now. I appreciate it! Am 24.03.20 um 00:56 schrieb Amara Emerson:> Hi Dominik, > >> On Mar 12, 2020, at 9:46 AM, Dominik Montada <dominik.montada at hightec-rt.com> wrote: >> >> Hi Quentin, >> >> thank you for the reply! I have a couple more questions that came up when I tried to implement this today. I hope you can help me out with this again! >> >> Am 09.03.20 um 23:31 schrieb Quentin Colombet: >>> I would expect that you could create a register class and register bank for the special register. That way you have something to map to when you do register bank select. >>> The register class could be "not allocatable” (see CCR in AArch64 for instance). >>> Note, that if that class is unallocable, you’ll have to manage manually any overlapping that could arise. >>> E.g., >>> s32 ..., s1 carry1 = G_UADDO >>> s32 ..., s1 carry2 = G_UADDO >>> s32 extended_carry1 = zext s1 carry1 <— carry1 will be destroyed by the second G_UADDO, you’ll have to fix the schedule or copy the value manually. >>> s32 extended_carry2 = zext s1 carry2 >>> icmp s32 extended_carry1, extended_carry2 >> So before instruction selection we would need to check if there are any overlaps and if so try to fix them if possible or abort compilation if that is not possible? >>> Then when you do instruction selection, just map the register to the physical register. (You may want to do the fix-ups I mentioned here.) >> What exactly do you mean by "map the register to the physical register"? Do you mean that I should just emit a COPY from/to this physical register and constrain the virtual register to the non-allocatable register class? Because this actually gives me an assertion that the register class must be allocatable. Or do you mean to use the physical register in the target instruction instead of the virtual one (i.e. drop the usage of the virtual register and replace it with the physical register)? The target instruction uses the physical register implicitly by the way. >> >> I also tried to take a look at how AArch64 implements G_UADDO/G_UADDE but it doesn't seem to fully implement selection for those? Maybe I just didn't read the code properly… > AArch64 doesn’t use the condition register bank, it was added before I joined the project so I’m not entirely sure what the intent was. However, the condition register side effect is something that we explicitly capture in SSA variables by copying every definition into a GPR, for which we do have regbanks for. We do this by using CSET/CSINC instructions on AArch64 which allow us to set a GPR register using the value of the condition register. We do this in every selection of an instruction like G_ICMP or G_UADDO which may write write a flag output. > > %c1(s1) = G_ICMP eq, %foo, %bar > > …can be selected into > cmp x0, x1 > csinc x8, xzr, xzr, eq > > Which results in the %c1 value being written to the register x8. Because we select in this way, we don’t have any extra side effects to model before selection time. It’s all in SSA. We then have selection patterns that try to optimize sequences like this if we can depending on the context.I see! And even if you can't optimize such a sequence it's not a problem because of the CSET/CSINC instructions, correct? This is basically what is missing on our architecture to make this work (nicely). I guess if we would have tried to combine such sequences after selection, we would most likely have been fine for the vast majority of programs. But since we don't have an equivalent to these two instructions on our architecture, we would still have to cover the case where we cannot optimize it and either repair or reject it. In the end I think we were able to come up with a good solution that is working for us (thanks again Quentin!) but it is always interesting to see how other backends solve similar problems. Thanks to everyone involved! Cheers, Dominik> > For G_UADDO, you can see in the selector code that we emit an ADDS flag setting instruction, and then extract the carry flag using a CSET into the carry destination virtual register. > > Cheers, > Amara >>> I would expect that you could create a register class and register bank for the special register. That way you have something to map to when you do register bank select. >>> >> I looked at the CC regbank of AArch64, however I didn't see any mappings using it in RegBankInfo. Is that something that AArch64 simply hasn't implemented or is there something going on that I'm not seeing. I mean, what is the point to have a register bank when it is not used during regbankselect? I would at least expect that for example G_UADDO would use this register bank for the s1 carry out. >>> Generally speaking, I think you would need a copy (or zext/sext) to move the value in general purpose land (like in my example with zext). If you don’t have such use, the copy wouldn’t be emitted and there is nothing to do. >>> >>> To be honest, I think the situation is complicated today because GISel lack the fix-up that I mentioned. I am actually surprised that didn’t come up as an issue yet (x86 is full of these flags). Going forward, I think it should just come with the framework: you assign a physreg selection time, GISel copies it around/reschedule appropriately to preserve the value. There’s a lot of wishful thinking here x). >>> >>> Cheers, >>> -Quentin >>> >> Best regards, >> >> Dominik >> >> -- >> ---------------------------------------------------------------------- >> Dominik Montada Email: dominik.montada at hightec-rt.com >> HighTec EDV-Systeme GmbH Phone: +49 681 92613 19 >> Europaallee 19 Fax: +49-681-92613-26 >> D-66113 Saarbrücken WWW: http://www.hightec-rt.com >> >> Managing Director: Vera Strothmann >> Register Court: Saarbrücken, HRB 10445, VAT ID: DE 138344222 >> >> This e-mail may contain confidential and/or privileged information. If >> you are not the intended recipient please notify the sender immediately >> and destroy this e-mail. Any unauthorised copying, disclosure or >> distribution of the material in this e-mail is strictly forbidden. >> --- >> >-- ---------------------------------------------------------------------- Dominik Montada Email: dominik.montada at hightec-rt.com HighTec EDV-Systeme GmbH Phone: +49 681 92613 19 Europaallee 19 Fax: +49-681-92613-26 D-66113 Saarbrücken WWW: http://www.hightec-rt.com Managing Director: Vera Strothmann Register Court: Saarbrücken, HRB 10445, VAT ID: DE 138344222 This e-mail may contain confidential and/or privileged information. If you are not the intended recipient please notify the sender immediately and destroy this e-mail. Any unauthorised copying, disclosure or distribution of the material in this e-mail is strictly forbidden. --- -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 5409 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200324/3e045acb/attachment.bin>