1. 03 3月, 2017 1 次提交
    • L
      give up on gcc ilog2() constant optimizations · 474c9015
      Linus Torvalds 提交于
      gcc-7 has an "optimization" pass that completely screws up, and
      generates the code expansion for the (impossible) case of calling
      ilog2() with a zero constant, even when the code gcc compiles does not
      actually have a zero constant.
      
      And we try to generate a compile-time error for anybody doing ilog2() on
      a constant where that doesn't make sense (be it zero or negative).  So
      now gcc7 will fail the build due to our sanity checking, because it
      created that constant-zero case that didn't actually exist in the source
      code.
      
      There's a whole long discussion on the kernel mailing about how to work
      around this gcc bug.  The gcc people themselevs have discussed their
      "feature" in
      
         https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72785
      
      but it's all water under the bridge, because while it looked at one
      point like it would be solved by the time gcc7 was released, that was
      not to be.
      
      So now we have to deal with this compiler braindamage.
      
      And the only simple approach seems to be to just delete the code that
      tries to warn about bad uses of ilog2().
      
      So now "ilog2()" will just return 0 not just for the value 1, but for
      any non-positive value too.
      
      It's not like I can recall anybody having ever actually tried to use
      this function on any invalid value, but maybe the sanity check just
      meant that such code never made it out in public.
      Reported-by: NLaura Abbott <labbott@redhat.com>
      Cc: John Stultz <john.stultz@linaro.org>,
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      474c9015
  2. 04 2月, 2017 1 次提交
  3. 13 12月, 2011 1 次提交
    • L
      linux/log2.h: Fix rounddown_pow_of_two(1) · 13c07b02
      Linus Torvalds 提交于
      Exactly like roundup_pow_of_two(1), the rounddown version was buggy for
      the case of a compile-time constant '1' argument.  Probably because it
      originated from the same code, sharing history with the roundup version
      from before the bugfix (for that one, see commit 1a06a52e: "Fix
      roundup_pow_of_two(1)").
      
      However, unlike the roundup version, the fix for rounddown is to just
      remove the broken special case entirely.  It's simply not needed - the
      generic code
      
          1UL << ilog2(n)
      
      does the right thing for the constant '1' argment too.  The only reason
      roundup needed that special case was because rounding up does so by
      subtracting one from the argument (and then adding one to the result)
      causing the obvious problems with "ilog2(0)".
      
      But rounddown doesn't do any of that, since ilog2() naturally truncates
      (ie "rounds down") to the right rounded down value.  And without the
      ilog2(0) case, there's no reason for the special case that had the wrong
      value.
      
      tl;dr: rounddown_pow_of_two(1) should be 1, not 0.
      Acked-by: NDmitry Torokhov <dtor@vmware.com>
      Cc: stable@kernel.org
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      13c07b02
  4. 07 2月, 2008 1 次提交
  5. 17 10月, 2007 1 次提交
  6. 19 5月, 2007 1 次提交
  7. 18 2月, 2007 1 次提交
  8. 07 2月, 2007 1 次提交
  9. 09 12月, 2006 2 次提交
    • D
      [PATCH] LOG2: Alter roundup_pow_of_two() so that it can use a ilog2() on a constant · 312a0c17
      David Howells 提交于
      Alter roundup_pow_of_two() so that it can make use of ilog2() on a constant to
      produce a constant value, retaining the ability for an arch to override it in
      the non-const case.
      
      This permits the function to be used to initialise variables.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
      Cc: Paul Mackerras <paulus@samba.org>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      312a0c17
    • D
      [PATCH] LOG2: Implement a general integer log2 facility in the kernel · f0d1b0b3
      David Howells 提交于
      This facility provides three entry points:
      
      	ilog2()		Log base 2 of unsigned long
      	ilog2_u32()	Log base 2 of u32
      	ilog2_u64()	Log base 2 of u64
      
      These facilities can either be used inside functions on dynamic data:
      
      	int do_something(long q)
      	{
      		...;
      		y = ilog2(x)
      		...;
      	}
      
      Or can be used to statically initialise global variables with constant values:
      
      	unsigned n = ilog2(27);
      
      When performing static initialisation, the compiler will report "error:
      initializer element is not constant" if asked to take a log of zero or of
      something not reducible to a constant.  They treat negative numbers as
      unsigned.
      
      When not dealing with a constant, they fall back to using fls() which permits
      them to use arch-specific log calculation instructions - such as BSR on
      x86/x86_64 or SCAN on FRV - if available.
      
      [akpm@osdl.org: MMC fix]
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
      Cc: Paul Mackerras <paulus@samba.org>
      Cc: Herbert Xu <herbert@gondor.apana.org.au>
      Cc: David Howells <dhowells@redhat.com>
      Cc: Wojtek Kaniewski <wojtekka@toxygen.net>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      f0d1b0b3