Use sext in fast isel.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 6 Apr 2015 22:29:07 +0000 (22:29 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 6 Apr 2015 22:29:07 +0000 (22:29 +0000)
Fast isel used to zero extends immediates to 64 bits. This normally goes
unnoticed because the value is truncated to 32 bits for output.

Two cases were it is noticed:

* We fail to use smaller encodings.
* If the original constant was smaller than i32.

In the tests using i1 constants, codegen would change to use -1, which is fine
(and matches what regular isel does) since only the lowest bit is then used.

Instead, this patch then changes the ir to use i8 constants, which looks more
like what clang produces.

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

lib/CodeGen/SelectionDAG/FastISel.cpp
test/CodeGen/Mips/Fast-ISel/logopm.ll
test/CodeGen/X86/fast-isel-i1.ll
test/CodeGen/X86/fast-isel-sext.ll [new file with mode: 0644]

index 8f504e152d0b0463bfd54f2889e1b4d9263a56d6..cf26425074ae8d22f1e8e460b60ee94edbf81319 100644 (file)
@@ -425,7 +425,7 @@ bool FastISel::selectBinaryOp(const User *I, unsigned ISDOpcode) {
 
   // Check if the second operand is a constant and handle it appropriately.
   if (const auto *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
-    uint64_t Imm = CI->getZExtValue();
+    uint64_t Imm = CI->getSExtValue();
 
     // Transform "sdiv exact X, 8" -> "sra X, 3".
     if (ISDOpcode == ISD::SDIV && isa<BinaryOperator>(I) &&
index cfb751fe178f613223130de67c866d11a02333de..0f0c3bf9e1dc74580b05e8eec1e375e782b51ee0 100644 (file)
@@ -68,11 +68,12 @@ entry:
 
 ; Function Attrs: noinline nounwind
 define void @andUb1() #0 {
+; clang uses i8 constants for booleans, so we test with an i8 1.
 entry:
-  %0 = load i8, i8* @ub1, align 1, !tbaa !2
-  %conv = trunc i8 %0 to i1
-  %and = and i1 %conv, 1
-  %conv1 = zext i1 %and to i8
+  %x = load i8, i8* @ub1, align 1, !tbaa !2
+  %and = and i8 %x, 1
+  %conv = trunc i8 %and to i1
+  %conv1 = zext i1 %conv to i8
   store i8 %conv1, i8* @ub, align 1, !tbaa !2
 ; CHECK-LABEL:  .ent    andUb1
 ; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
@@ -138,10 +139,10 @@ entry:
 ; Function Attrs: noinline nounwind
 define void @orUb1() #0 {
 entry:
-  %0 = load i8, i8* @ub1, align 1, !tbaa !2
-  %conv = trunc i8 %0 to i1
-  %or = or i1 %conv, 1
-  %conv1 = zext i1 %or to i8
+  %x = load i8, i8* @ub1, align 1, !tbaa !2
+  %or = or i8 %x, 1
+  %conv = trunc i8 %or to i1
+  %conv1 = zext i1 %conv to i8
   store i8 %conv1, i8* @ub, align 1, !tbaa !2
 ; CHECK-LABEL:  .ent    orUb1
 ; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
@@ -208,10 +209,10 @@ entry:
 ; Function Attrs: noinline nounwind
 define void @xorUb1() #0 {
 entry:
-  %0 = load i8, i8* @ub1, align 1, !tbaa !2
-  %conv = trunc i8 %0 to i1
-  %xor = xor i1 %conv, 1
-  %conv1 = zext i1 %xor to i8
+  %x = load i8, i8* @ub1, align 1, !tbaa !2
+  %xor = xor i8 1, %x
+  %conv = trunc i8 %xor to i1
+  %conv1 = zext i1 %conv to i8
   store i8 %conv1, i8* @ub, align 1, !tbaa !2
 ; CHECK-LABEL:  .ent    xorUb1
 ; CHECK:        lui     $[[REG_GPa:[0-9]+]], %hi(_gp_disp)
index d72a31ce354f3d9797b4519cff3769cea5d387e1..589de76617a00ae38aeb7d7aae5b17ce075c741c 100644 (file)
@@ -23,14 +23,15 @@ exit:               ; preds = %next
 
 define void @test2(i8* %a) nounwind {
 entry:
+; clang uses i8 constants for booleans, so we test with an i8 1.
 ; CHECK-LABEL: test2:
 ; CHECK: movb {{.*}} %al
 ; CHECK-NEXT: xorb $1, %al
 ; CHECK-NEXT: testb $1
   %tmp = load i8, i8* %a, align 1
-  %tobool = trunc i8 %tmp to i1
-  %tobool2 = xor i1 %tobool, true
-  br i1 %tobool2, label %if.then, label %if.end
+  %xor = xor i8 %tmp, 1
+  %tobool = trunc i8 %xor to i1
+  br i1 %tobool, label %if.then, label %if.end
 
 if.then:
   call void @test2(i8* null)
diff --git a/test/CodeGen/X86/fast-isel-sext.ll b/test/CodeGen/X86/fast-isel-sext.ll
new file mode 100644 (file)
index 0000000..ca1558e
--- /dev/null
@@ -0,0 +1,9 @@
+; RUN: llc -mtriple=x86_64-linux -fast-isel -show-mc-encoding < %s | FileCheck %s
+
+; CHECK-LABEL: f:
+; CHECK:       addl $-2, %eax         # encoding: [0x83,0xc0,0xfe]
+define i32 @f(i32* %y) {
+  %x = load i32, i32* %y
+  %dec = add i32 %x, -2
+  ret i32 %dec
+}