From 7bdc1cb69019584854c3292263b6c6ddabda1bb2 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 6 Apr 2015 22:29:07 +0000 Subject: [PATCH] Use sext in fast isel. 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 | 2 +- test/CodeGen/Mips/Fast-ISel/logopm.ll | 25 +++++++++++++------------ test/CodeGen/X86/fast-isel-i1.ll | 7 ++++--- test/CodeGen/X86/fast-isel-sext.ll | 9 +++++++++ 4 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 test/CodeGen/X86/fast-isel-sext.ll diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index 8f504e152d0..cf26425074a 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -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(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(I) && diff --git a/test/CodeGen/Mips/Fast-ISel/logopm.ll b/test/CodeGen/Mips/Fast-ISel/logopm.ll index cfb751fe178..0f0c3bf9e1d 100644 --- a/test/CodeGen/Mips/Fast-ISel/logopm.ll +++ b/test/CodeGen/Mips/Fast-ISel/logopm.ll @@ -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) diff --git a/test/CodeGen/X86/fast-isel-i1.ll b/test/CodeGen/X86/fast-isel-i1.ll index d72a31ce354..589de76617a 100644 --- a/test/CodeGen/X86/fast-isel-i1.ll +++ b/test/CodeGen/X86/fast-isel-i1.ll @@ -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 index 00000000000..ca1558e3c84 --- /dev/null +++ b/test/CodeGen/X86/fast-isel-sext.ll @@ -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 +} -- 2.34.1