The signed version of our "magic number" computation for the integer approximation
authorCameron Zwarich <zwarich@apple.com>
Mon, 21 Feb 2011 00:22:02 +0000 (00:22 +0000)
committerCameron Zwarich <zwarich@apple.com>
Mon, 21 Feb 2011 00:22:02 +0000 (00:22 +0000)
of a constant had a minor typo introduced when copying it from the book, which
caused it to favor negative approximations over positive approximations in many
cases. Positive approximations require fewer operations beyond the multiplication.

In the case of division by 3, we still generate code that is a single instruction
larger than GCC's code.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126097 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/APInt.cpp
lib/Target/X86/README.txt
test/CodeGen/X86/divide-by-constant.ll
unittests/ADT/APIntTest.cpp

index 77033428b577dd7aca8b2a19ea3be65febb3f868..08f36d2af3a1e848820ef36c62eb7ed24b01067d 100644 (file)
@@ -1505,7 +1505,7 @@ APInt::ms APInt::magic() const {
       r2 = r2 - ad;
     }
     delta = ad - r2;
-  } while (q1.ule(delta) || (q1 == delta && r1 == 0));
+  } while (q1.ult(delta) || (q1 == delta && r1 == 0));
 
   mag.m = q2 + 1;
   if (d.isNegative()) mag.m = -mag.m;   // resulting magic number
index c10e1709f667792b4588019a674e30a410839db2..ed3bff150bcf24ee8bb3f00223805e0dd126f434 100644 (file)
@@ -1888,12 +1888,10 @@ Compiles to: $clang t.c -S -o - -O3 -mkernel -fomit-frame-pointer
 
 _t:                                     ## @t
        movslq  %edi, %rax
-       imulq   $-1431655765, %rax, %rcx ## imm = 0xFFFFFFFFAAAAAAAB
-       shrq    $32, %rcx
-       addl    %ecx, %eax
-       movl    %eax, %ecx
-       shrl    $31, %ecx
-       shrl    %eax
+       imulq   $1431655766, %rax, %rax ## imm = 0x55555556
+       movq    %rax, %rcx
+       shrq    $63, %rcx
+       shrq    $32, %rax
        addl    %ecx, %eax
        movsbl  %al, %eax
        ret
index 7ceb972f61bbf07f3f1e541272197c4b69270092..fe335b9369cbc55299057c42ca82964d423f9e43 100644 (file)
@@ -40,7 +40,7 @@ entry:
        %div = sdiv i16 %x, 33          ; <i32> [#uses=1]
        ret i16 %div
 ; CHECK: test4:
-; CHECK: imull $-1985, %ecx, %ec
+; CHECK: imull $1986, %eax, %ea
 }
 
 define i32 @test5(i32 %A) nounwind {
index 557d835bacda0f81a45553d22632d92fda7d61a1..e05bdbfc710194c796a383539ca97d0d63e4c700 100644 (file)
@@ -332,6 +332,24 @@ TEST(APIntTest, Log2) {
   EXPECT_EQ(APInt(15, 9).exactLogBase2(), -1);
 }
 
+TEST(APIntTest, magic) {
+  EXPECT_EQ(APInt(32, 3).magic().m, APInt(32, "55555556", 16));
+  EXPECT_EQ(APInt(32, 3).magic().s, 0U);
+  EXPECT_EQ(APInt(32, 5).magic().m, APInt(32, "66666667", 16));
+  EXPECT_EQ(APInt(32, 5).magic().s, 1U);
+  EXPECT_EQ(APInt(32, 7).magic().m, APInt(32, "92492493", 16));
+  EXPECT_EQ(APInt(32, 7).magic().s, 2U);
+}
+
+TEST(APIntTest, magicu) {
+  EXPECT_EQ(APInt(32, 3).magicu().m, APInt(32, "AAAAAAAB", 16));
+  EXPECT_EQ(APInt(32, 3).magicu().s, 1U);
+  EXPECT_EQ(APInt(32, 5).magicu().m, APInt(32, "CCCCCCCD", 16));
+  EXPECT_EQ(APInt(32, 5).magicu().s, 2U);
+  EXPECT_EQ(APInt(32, 7).magicu().m, APInt(32, "24924925", 16));
+  EXPECT_EQ(APInt(32, 7).magicu().s, 3U);
+}
+
 #ifdef GTEST_HAS_DEATH_TEST
 #ifndef NDEBUG
 TEST(APIntTest, StringDeath) {