alexp via llvm-dev
2019-Feb-25 14:09 UTC
[llvm-dev] Why is there still ineffective code after -o3 optimization?
Hi, I have some IR module from random generation (mostly ineffective instructions). It has a function with void return, and two function arguments where one is a reference. Therefore, I expect every instruction not altering the value at the 2nd arguments address should be ineffective. Here is the function definition (see below for full ll): define void @_Z27entityMainDataInputCallbackdRd(double %input, double* dereferenceable(8) %o0) local_unnamed_addr #0 { The ll below has been optimized using opt -O3 -S input.ll -o out.ll The cfg is plotted as png here: https://ibb.co/f1B0rnm My question is: why is there still some unnecessary 'lint' in the optimization result? E.G. from the splittedblock19 onwards: there is one effective instruction store double 0x3FF787378698A951, double* %o0 everything what follows (conditional branch, splittedblock38, 21, 42) could safely be removed (just leaving a 'ret void' after the store instruction). Why is this not removed? Is there a pass (combination) which could remove all the ineffective instructions? Thanks Alex //=====================================================//=== full ll below ; ModuleID = '0.1.800866.ll' source_filename = "entityMain.cpp" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" ; Function Attrs: noinline nounwind optnone uwtable define void @_Z27entityMainDataInputCallbackdRd(double %input, double* dereferenceable(8) %o0) local_unnamed_addr #0 { entry: %input.addr = alloca double, align 8 %o0.addr = alloca double*, align 8 %ui = alloca i32, align 4 store double %input, double* %input.addr, align 8 %0 = fptoui double %input to i64 %1 = fptrunc double %input to float %2 = mul i64 %0, %0 %3 = fptrunc double %input to float %4 = mul i64 %0, %0 %5 = fsub float %3, %3 store double* %o0, double** %o0.addr %6 = and i64 %0, %0 %7 = fptoui float %3 to i1 %8 = ashr i1 %7, %7 store double* null, double** %o0.addr %9 = fptosi double %input to i64 %10 = shl i1 %7, %7 %11 = sitofp i1 %8 to float %12 = icmp uge i64 %6, %4 %13 = and i64 %0, %6 %14 = fcmp ole float %11, %11 %15 = ashr i1 %10, %7 %16 = sext i1 %10 to i64 %17 = ashr i1 %7, %12 %18 = alloca [2 x double] %19 = fcmp true float %11, %3 br label %splittedblock7 splittedblock7: ; preds = %entry %20 = select i1 %8, i1 %17, i1 %19 %21 = fptoui float %1 to i1 br label %splittedblock1 splittedblock1: ; preds = %splittedblock7 %22 = fptrunc double %input to float %23 = shl i1 %17, %20 %24 = fsub float %5, %5 br label %splittedblock35 splittedblock36: ; preds = %splittedblock10 br label %splittedblock15 splittedblock38: ; preds = %splittedblock19 br label %splittedblock21 splittedblock10: ; preds = %splittedblock35 br label %splittedblock36 splittedblock35: ; preds = %splittedblock1 br i1 %12, label %splittedblock14, label %splittedblock10 splittedblock14: ; preds = %splittedblock35 br label %splittedblock19 splittedblock19: ; preds = %splittedblock14 store double 0x3FF787378698A951, double* %o0 br i1 %23, label %splittedblock38, label %splittedblock42 splittedblock42: ; preds %splittedblock21, %splittedblock19 ret void splittedblock15: ; preds = %splittedblock36 ret void splittedblock21: ; preds = %splittedblock38 %25 = xor i64 %6, %4 br label %splittedblock42 } ; Function Attrs: norecurse nounwind readnone define <2 x double> @func_3701811888700380719897139(...) local_unnamed_addr #1 { entry: ret <2 x double> <double 0xC00934F9D7726A00, double 0xFFCFDA8E9AFFB51D> } ; Function Attrs: norecurse noreturn nounwind readnone define { double, double } @func_0065559471331315590586(...) local_unnamed_addr #2 { entry: br label %splittedblock1 splittedblock1: ; preds = %entry, %splittedblock1 br label %splittedblock1 } attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { norecurse nounwind readnone } attributes #2 = { norecurse noreturn nounwind readnone } !llvm.module.flags = !{!0, !1} !llvm.ident = !{!2} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{i32 7, !"PIC Level", i32 2} !2 = !{!"clang version 7.0.1 (branches/release_70 348238)"}
Pedro Olsen Ferreira via llvm-dev
2019-Feb-25 14:27 UTC
[llvm-dev] Why is there still ineffective code after -o3 optimization?
You're asking LLVM not to optimise that function: define void @_Z27entityMainDataInputCallbackdRd(double %input, double* dereferenceable(8) %o0) local_unnamed_addr #0 where the attribute list is defined as: attributes #0 = { noinline nounwind optnone uwtable Removing "optnone" yields what you'd expect. On 25/02/2019 14:09, alexp via llvm-dev wrote: Hi, I have some IR module from random generation (mostly ineffective instructions). It has a function with void return, and two function arguments where one is a reference. Therefore, I expect every instruction not altering the value at the 2nd arguments address should be ineffective. Here is the function definition (see below for full ll): define void @_Z27entityMainDataInputCallbackdRd(double %input, double* dereferenceable(8) %o0) local_unnamed_addr #0 { The ll below has been optimized using opt -O3 -S input.ll -o out.ll The cfg is plotted as png here: https://ibb.co/f1B0rnm My question is: why is there still some unnecessary 'lint' in the optimization result? E.G. from the splittedblock19 onwards: there is one effective instruction store double 0x3FF787378698A951, double* %o0 everything what follows (conditional branch, splittedblock38, 21, 42) could safely be removed (just leaving a 'ret void' after the store instruction). Why is this not removed? Is there a pass (combination) which could remove all the ineffective instructions? Thanks Alex //=====================================================//=== full ll below ; ModuleID = '0.1.800866.ll' source_filename = "entityMain.cpp" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" ; Function Attrs: noinline nounwind optnone uwtable define void @_Z27entityMainDataInputCallbackdRd(double %input, double* dereferenceable(8) %o0) local_unnamed_addr #0 { entry: %input.addr = alloca double, align 8 %o0.addr = alloca double*, align 8 %ui = alloca i32, align 4 store double %input, double* %input.addr, align 8 %0 = fptoui double %input to i64 %1 = fptrunc double %input to float %2 = mul i64 %0, %0 %3 = fptrunc double %input to float %4 = mul i64 %0, %0 %5 = fsub float %3, %3 store double* %o0, double** %o0.addr %6 = and i64 %0, %0 %7 = fptoui float %3 to i1 %8 = ashr i1 %7, %7 store double* null, double** %o0.addr %9 = fptosi double %input to i64 %10 = shl i1 %7, %7 %11 = sitofp i1 %8 to float %12 = icmp uge i64 %6, %4 %13 = and i64 %0, %6 %14 = fcmp ole float %11, %11 %15 = ashr i1 %10, %7 %16 = sext i1 %10 to i64 %17 = ashr i1 %7, %12 %18 = alloca [2 x double] %19 = fcmp true float %11, %3 br label %splittedblock7 splittedblock7: ; preds = %entry %20 = select i1 %8, i1 %17, i1 %19 %21 = fptoui float %1 to i1 br label %splittedblock1 splittedblock1: ; preds = %splittedblock7 %22 = fptrunc double %input to float %23 = shl i1 %17, %20 %24 = fsub float %5, %5 br label %splittedblock35 splittedblock36: ; preds = %splittedblock10 br label %splittedblock15 splittedblock38: ; preds = %splittedblock19 br label %splittedblock21 splittedblock10: ; preds = %splittedblock35 br label %splittedblock36 splittedblock35: ; preds = %splittedblock1 br i1 %12, label %splittedblock14, label %splittedblock10 splittedblock14: ; preds = %splittedblock35 br label %splittedblock19 splittedblock19: ; preds = %splittedblock14 store double 0x3FF787378698A951, double* %o0 br i1 %23, label %splittedblock38, label %splittedblock42 splittedblock42: ; preds %splittedblock21, %splittedblock19 ret void splittedblock15: ; preds = %splittedblock36 ret void splittedblock21: ; preds = %splittedblock38 %25 = xor i64 %6, %4 br label %splittedblock42 } ; Function Attrs: norecurse nounwind readnone define <2 x double> @func_3701811888700380719897139(...) local_unnamed_addr #1 { entry: ret <2 x double> <double 0xC00934F9D7726A00, double 0xFFCFDA8E9AFFB51D> } ; Function Attrs: norecurse noreturn nounwind readnone define { double, double } @func_0065559471331315590586(...) local_unnamed_addr #2 { entry: br label %splittedblock1 splittedblock1: ; preds = %entry, %splittedblock1 br label %splittedblock1 } attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { norecurse nounwind readnone } attributes #2 = { norecurse noreturn nounwind readnone } !llvm.module.flags = !{!0, !1} !llvm.ident = !{!2} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{i32 7, !"PIC Level", i32 2} !2 = !{!"clang version 7.0.1 (branches/release_70 348238)"} _______________________________________________ LLVM Developers mailing list llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190225/0b029668/attachment.html>
via llvm-dev
2019-Feb-25 21:09 UTC
[llvm-dev] Why is there still ineffective code after -o3 optimization?
If you produced the .ll file with a command line along the lines of `clang –c –O0 –emit-llvm …` then the IR functions will be annotated with the `optnone` attribute. If you don't want that, a better command line would be `clang –c –O2 –Xclang –disable-llvm-passes –emit-llvm …` --paulr From: llvm-dev [mailto:llvm-dev-bounces at lists.llvm.org] On Behalf Of Pedro Olsen Ferreira via llvm-dev Sent: Monday, February 25, 2019 6:28 AM To: llvm-dev at lists.llvm.org Subject: Re: [llvm-dev] Why is there still ineffective code after -o3 optimization? You're asking LLVM not to optimise that function: define void @_Z27entityMainDataInputCallbackdRd(double %input, double* dereferenceable(8) %o0) local_unnamed_addr #0 where the attribute list is defined as: attributes #0 = { noinline nounwind optnone uwtable Removing "optnone" yields what you'd expect. On 25/02/2019 14:09, alexp via llvm-dev wrote: Hi, I have some IR module from random generation (mostly ineffective instructions). It has a function with void return, and two function arguments where one is a reference. Therefore, I expect every instruction not altering the value at the 2nd arguments address should be ineffective. Here is the function definition (see below for full ll): define void @_Z27entityMainDataInputCallbackdRd(double %input, double* dereferenceable(8) %o0) local_unnamed_addr #0 { The ll below has been optimized using opt -O3 -S input.ll -o out.ll The cfg is plotted as png here: https://ibb.co/f1B0rnm My question is: why is there still some unnecessary 'lint' in the optimization result? E.G. from the splittedblock19 onwards: there is one effective instruction store double 0x3FF787378698A951, double* %o0 everything what follows (conditional branch, splittedblock38, 21, 42) could safely be removed (just leaving a 'ret void' after the store instruction). Why is this not removed? Is there a pass (combination) which could remove all the ineffective instructions? Thanks Alex //===================================================== //=== full ll below ; ModuleID = '0.1.800866.ll' source_filename = "entityMain.cpp" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" ; Function Attrs: noinline nounwind optnone uwtable define void @_Z27entityMainDataInputCallbackdRd(double %input, double* dereferenceable(8) %o0) local_unnamed_addr #0 { entry: %input.addr = alloca double, align 8 %o0.addr = alloca double*, align 8 %ui = alloca i32, align 4 store double %input, double* %input.addr, align 8 %0 = fptoui double %input to i64 %1 = fptrunc double %input to float %2 = mul i64 %0, %0 %3 = fptrunc double %input to float %4 = mul i64 %0, %0 %5 = fsub float %3, %3 store double* %o0, double** %o0.addr %6 = and i64 %0, %0 %7 = fptoui float %3 to i1 %8 = ashr i1 %7, %7 store double* null, double** %o0.addr %9 = fptosi double %input to i64 %10 = shl i1 %7, %7 %11 = sitofp i1 %8 to float %12 = icmp uge i64 %6, %4 %13 = and i64 %0, %6 %14 = fcmp ole float %11, %11 %15 = ashr i1 %10, %7 %16 = sext i1 %10 to i64 %17 = ashr i1 %7, %12 %18 = alloca [2 x double] %19 = fcmp true float %11, %3 br label %splittedblock7 splittedblock7: ; preds = %entry %20 = select i1 %8, i1 %17, i1 %19 %21 = fptoui float %1 to i1 br label %splittedblock1 splittedblock1: ; preds = %splittedblock7 %22 = fptrunc double %input to float %23 = shl i1 %17, %20 %24 = fsub float %5, %5 br label %splittedblock35 splittedblock36: ; preds = %splittedblock10 br label %splittedblock15 splittedblock38: ; preds = %splittedblock19 br label %splittedblock21 splittedblock10: ; preds = %splittedblock35 br label %splittedblock36 splittedblock35: ; preds = %splittedblock1 br i1 %12, label %splittedblock14, label %splittedblock10 splittedblock14: ; preds = %splittedblock35 br label %splittedblock19 splittedblock19: ; preds = %splittedblock14 store double 0x3FF787378698A951, double* %o0 br i1 %23, label %splittedblock38, label %splittedblock42 splittedblock42: ; preds %splittedblock21, %splittedblock19 ret void splittedblock15: ; preds = %splittedblock36 ret void splittedblock21: ; preds = %splittedblock38 %25 = xor i64 %6, %4 br label %splittedblock42 } ; Function Attrs: norecurse nounwind readnone define <2 x double> @func_3701811888700380719897139(...) local_unnamed_addr #1 { entry: ret <2 x double> <double 0xC00934F9D7726A00, double 0xFFCFDA8E9AFFB51D> } ; Function Attrs: norecurse noreturn nounwind readnone define { double, double } @func_0065559471331315590586(...) local_unnamed_addr #2 { entry: br label %splittedblock1 splittedblock1: ; preds = %entry, %splittedblock1 br label %splittedblock1 } attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { norecurse nounwind readnone } attributes #2 = { norecurse noreturn nounwind readnone } !llvm.module.flags = !{!0, !1} !llvm.ident = !{!2} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{i32 7, !"PIC Level", i32 2} !2 = !{!"clang version 7.0.1 (branches/release_70 348238)"} _______________________________________________ LLVM Developers mailing list llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190225/b35690d0/attachment-0001.html>
alexp via llvm-dev
2019-Feb-26 12:37 UTC
[llvm-dev] Why is there still ineffective code after -o3 optimization?
Oh, I did not see the obvious! Thanks a lot! Alex On 2/25/19 3:27 PM, Pedro Olsen Ferreira via llvm-dev wrote:> You're asking LLVM not to optimise that function: > > define void @_Z27entityMainDataInputCallbackdRd(double %input, double* > dereferenceable(8) %o0) local_unnamed_addr *#0 *where the attribute list is defined as: > > attributes #0 = { noinline nounwind *optnone* uwtable > > > > Removing "optnone" yields what you'd expect. > ** > > > > On 25/02/2019 14:09, alexp via llvm-dev wrote: >> Hi, >> >> I have some IR module from random generation (mostly ineffective >> instructions). >> It has a function with void return, and two function arguments where one >> is a reference. >> Therefore, I expect every instruction not altering the value at the 2nd >> arguments address should be ineffective. >> >> Here is the function definition (see below for full ll): >> >> define void @_Z27entityMainDataInputCallbackdRd(double %input, double* >> dereferenceable(8) %o0) local_unnamed_addr #0 { >> >> The ll below has been optimized using opt -O3 -S input.ll -o out.ll >> The cfg is plotted as png here: >> https://ibb.co/f1B0rnm >> >> My question is: why is there still some unnecessary 'lint' in the >> optimization result? >> E.G. from the splittedblock19 onwards: >> there is one effective instruction >> store double 0x3FF787378698A951, double* %o0 >> >> everything what follows (conditional branch, splittedblock38, 21, 42) >> could safely be removed (just leaving a 'ret void' after the store >> instruction). >> >> Why is this not removed? >> >> Is there a pass (combination) which could remove all the ineffective >> instructions? >> >> Thanks >> Alex >> >> >> >> >> //=====================================================>> //=== full ll below >> >> >> >> ; ModuleID = '0.1.800866.ll' >> source_filename = "entityMain.cpp" >> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" >> target triple = "x86_64-unknown-linux-gnu" >> >> ; Function Attrs: noinline nounwind optnone uwtable >> define void @_Z27entityMainDataInputCallbackdRd(double %input, double* >> dereferenceable(8) %o0) local_unnamed_addr #0 { >> entry: >> %input.addr = alloca double, align 8 >> %o0.addr = alloca double*, align 8 >> %ui = alloca i32, align 4 >> store double %input, double* %input.addr, align 8 >> %0 = fptoui double %input to i64 >> %1 = fptrunc double %input to float >> %2 = mul i64 %0, %0 >> %3 = fptrunc double %input to float >> %4 = mul i64 %0, %0 >> %5 = fsub float %3, %3 >> store double* %o0, double** %o0.addr >> %6 = and i64 %0, %0 >> %7 = fptoui float %3 to i1 >> %8 = ashr i1 %7, %7 >> store double* null, double** %o0.addr >> %9 = fptosi double %input to i64 >> %10 = shl i1 %7, %7 >> %11 = sitofp i1 %8 to float >> %12 = icmp uge i64 %6, %4 >> %13 = and i64 %0, %6 >> %14 = fcmp ole float %11, %11 >> %15 = ashr i1 %10, %7 >> %16 = sext i1 %10 to i64 >> %17 = ashr i1 %7, %12 >> %18 = alloca [2 x double] >> %19 = fcmp true float %11, %3 >> br label %splittedblock7 >> >> splittedblock7: ; preds = %entry >> %20 = select i1 %8, i1 %17, i1 %19 >> %21 = fptoui float %1 to i1 >> br label %splittedblock1 >> >> splittedblock1: ; preds = %splittedblock7 >> %22 = fptrunc double %input to float >> %23 = shl i1 %17, %20 >> %24 = fsub float %5, %5 >> br label %splittedblock35 >> >> splittedblock36: ; preds = %splittedblock10 >> br label %splittedblock15 >> >> splittedblock38: ; preds = %splittedblock19 >> br label %splittedblock21 >> >> splittedblock10: ; preds = %splittedblock35 >> br label %splittedblock36 >> >> splittedblock35: ; preds = %splittedblock1 >> br i1 %12, label %splittedblock14, label %splittedblock10 >> >> splittedblock14: ; preds = %splittedblock35 >> br label %splittedblock19 >> >> splittedblock19: ; preds = %splittedblock14 >> store double 0x3FF787378698A951, double* %o0 >> br i1 %23, label %splittedblock38, label %splittedblock42 >> >> splittedblock42: ; preds >> %splittedblock21, %splittedblock19 >> ret void >> >> splittedblock15: ; preds = %splittedblock36 >> ret void >> >> splittedblock21: ; preds = %splittedblock38 >> %25 = xor i64 %6, %4 >> br label %splittedblock42 >> } >> >> ; Function Attrs: norecurse nounwind readnone >> define <2 x double> @func_3701811888700380719897139(...) >> local_unnamed_addr #1 { >> entry: >> ret <2 x double> <double 0xC00934F9D7726A00, double 0xFFCFDA8E9AFFB51D> >> } >> >> ; Function Attrs: norecurse noreturn nounwind readnone >> define { double, double } @func_0065559471331315590586(...) >> local_unnamed_addr #2 { >> entry: >> br label %splittedblock1 >> >> splittedblock1: ; preds = %entry, >> %splittedblock1 >> br label %splittedblock1 >> } >> >> attributes #0 = { noinline nounwind optnone uwtable >> "correctly-rounded-divide-sqrt-fp-math"="false" >> "disable-tail-calls"="false" "less-precise-fpmad"="false" >> "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" >> "no-infs-fp-math"="false" "no-jump-tables"="false" >> "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" >> "no-trapping-math"="false" "stack-protector-buffer-size"="8" >> "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" >> "unsafe-fp-math"="false" "use-soft-float"="false" } >> attributes #1 = { norecurse nounwind readnone } >> attributes #2 = { norecurse noreturn nounwind readnone } >> >> !llvm.module.flags = !{!0, !1} >> !llvm.ident = !{!2} >> >> !0 = !{i32 1, !"wchar_size", i32 4} >> !1 = !{i32 7, !"PIC Level", i32 2} >> !2 = !{!"clang version 7.0.1 (branches/release_70 348238)"} >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > IMPORTANT NOTICE: The contents of this email and any attachments are > confidential and may also be privileged. If you are not the intended > recipient, please notify the sender immediately and do not disclose the > contents to any other person, use it for any purpose, or store or copy > the information in any medium. Thank you. > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >