From 812fde3603490eb140eb3ef29341dfe0d4e43c66 Mon Sep 17 00:00:00 2001 From: Weiming Zhao Date: Fri, 29 Jul 2016 23:33:48 +0000 Subject: [PATCH] DAG: avoid duplicated truncating for sign extended operand Summary: When performing cmp for EQ/NE and the operand is sign extended, we can avoid the truncaton if the bits to be tested are no less than origianl bits. Reviewers: eli.friedman Subscribers: eli.friedman, aemerson, nemanjai, t.p.northover, llvm-commits Differential Revision: https://reviews.llvm.org/D22933 llvm-svn: 277252 --- .../CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 18 ++-- llvm/test/CodeGen/AArch64/arm64-shrink-wrapping.ll | 3 +- llvm/test/CodeGen/ARM/arm-shrink-wrapping.ll | 10 +- .../test/CodeGen/ARM/no_redundant_trunc_for_cmp.ll | 105 +++++++++++++++++++++ llvm/test/CodeGen/PowerPC/ppc-shrink-wrapping.ll | 2 +- llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll | 3 +- 6 files changed, 125 insertions(+), 16 deletions(-) create mode 100644 llvm/test/CodeGen/ARM/no_redundant_trunc_for_cmp.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 3ab9459..020dac3 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -946,14 +946,16 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS, SDValue OpL = GetPromotedInteger(NewLHS); SDValue OpR = GetPromotedInteger(NewRHS); - // We would prefer to promote the comparison operand with sign extension, - // if we find the operand is actually to truncate an AssertSext. With this - // optimization, we can avoid inserting real truncate instruction, which - // is redudant eventually. - if (OpL->getOpcode() == ISD::AssertSext && - cast(OpL->getOperand(1))->getVT() == NewLHS.getValueType() && - OpR->getOpcode() == ISD::AssertSext && - cast(OpR->getOperand(1))->getVT() == NewRHS.getValueType()) { + // We would prefer to promote the comparison operand with sign extension. + // If the width of OpL/OpR excluding the duplicated sign bits is no greater + // than the width of NewLHS/NewRH, we can avoid inserting real truncate + // instruction, which is redudant eventually. + unsigned OpLEffectiveBits = + OpL.getValueType().getSizeInBits() - DAG.ComputeNumSignBits(OpL) + 1; + unsigned OpREffectiveBits = + OpR.getValueType().getSizeInBits() - DAG.ComputeNumSignBits(OpR) + 1; + if (OpLEffectiveBits <= NewLHS.getValueType().getSizeInBits() && + OpREffectiveBits <= NewRHS.getValueType().getSizeInBits()) { NewLHS = OpL; NewRHS = OpR; } else { diff --git a/llvm/test/CodeGen/AArch64/arm64-shrink-wrapping.ll b/llvm/test/CodeGen/AArch64/arm64-shrink-wrapping.ll index 16ae7ef..e39fae6 100644 --- a/llvm/test/CodeGen/AArch64/arm64-shrink-wrapping.ll +++ b/llvm/test/CodeGen/AArch64/arm64-shrink-wrapping.ll @@ -508,8 +508,7 @@ declare i32 @someVariadicFunc(i32, ...) ; CHECK-LABEL: noreturn: ; DISABLE: stp ; -; CHECK: and [[TEST:w[0-9]+]], w0, #0xff -; CHECK-NEXT: cbnz [[TEST]], [[ABORT:LBB[0-9_]+]] +; CHECK: cbnz w0, [[ABORT:LBB[0-9_]+]] ; ; CHECK: mov w0, #42 ; diff --git a/llvm/test/CodeGen/ARM/arm-shrink-wrapping.ll b/llvm/test/CodeGen/ARM/arm-shrink-wrapping.ll index cb608fc..93572b1 100644 --- a/llvm/test/CodeGen/ARM/arm-shrink-wrapping.ll +++ b/llvm/test/CodeGen/ARM/arm-shrink-wrapping.ll @@ -501,9 +501,13 @@ declare i32 @someVariadicFunc(i32, ...) ; ; CHECK-LABEL: noreturn: ; DISABLE: push -; -; CHECK: tst{{(\.w)?}} r0, #255 -; CHECK-NEXT: bne [[ABORT:LBB[0-9_]+]] +; ARM-ENABLE: cmp r0, #0 +; ARM-DISABLE: cmp r0, #0 +; ARM-ENABLE: bne [[ABORT:LBB[0-9_]+]] +; ARM-DISABLE: bne [[ABORT:LBB[0-9_]+]] +; THUMB-ENABLE: cbnz r0, [[ABORT:LBB[0-9_]+]] +; THUMB-DISABLE: cbnz r0, [[ABORT:LBB[0-9_]+]] + ; ; CHECK: mov{{s?}} r0, #42 ; diff --git a/llvm/test/CodeGen/ARM/no_redundant_trunc_for_cmp.ll b/llvm/test/CodeGen/ARM/no_redundant_trunc_for_cmp.ll new file mode 100644 index 0000000..7146c09 --- /dev/null +++ b/llvm/test/CodeGen/ARM/no_redundant_trunc_for_cmp.ll @@ -0,0 +1,105 @@ +; This test check if redundant truncate for eq/ne cmp is skipped during code gen. +;RUN: llc -mtriple=thumbv7-eabi < %s | FileCheck %s + +define void @test_zero(i16 signext %x) optsize { +;CHECK-LABEL: test_zero +entry: + %tobool = icmp eq i16 %x, 0 + br i1 %tobool, label %if.else, label %if.then +;CHECK-NOT: movw {{.*}}, #65535 +;CHECK: cbz r0, +if.then: ; preds = %entry + tail call void bitcast (void (...)* @foo1 to void ()*)() + br label %if.end + +if.else: ; preds = %entry + tail call void bitcast (void (...)* @foo2 to void ()*)() + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + +define void @test_i8_nonzero(i18 signext %x) optsize { +;CHECK-LABEL: test_i8_nonzero +entry: + %tobool = icmp eq i18 %x, 150 + br i1 %tobool, label %if.else, label %if.then +;CHECK-NOT: bfc +;CHECK: cmp r{{[0-9]+}}, #150 +if.then: ; preds = %entry + tail call void bitcast (void (...)* @foo1 to void ()*)() + br label %if.end + +if.else: ; preds = %entry + tail call void bitcast (void (...)* @foo2 to void ()*)() + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + +define void @test_i8_i16(i8 signext %x) optsize { +;CHECK-LABEL: test_i8_i16 +entry: + %x16 = sext i8 %x to i16 + %tobool = icmp eq i16 %x16, 300 + br i1 %tobool, label %if.else, label %if.then +;CHECK-NOT: uxth r0, r0 +;CHECK: cmp.w r0, #300 +if.then: ; preds = %entry + tail call void bitcast (void (...)* @foo1 to void ()*)() + br label %if.end + +if.else: ; preds = %entry + tail call void bitcast (void (...)* @foo2 to void ()*)() + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + +define void @test_i16_i8(i16 signext %x) optsize { +;CHECK-LABEL: test_i16_i8 +entry: +;CHECK: uxtb [[REG:r[0-9+]]], r0 +;CHECK: cmp [[REG]], #128 + %x8 = trunc i16 %x to i8 + %tobool = icmp eq i8 %x8, 128 + br i1 %tobool, label %if.else, label %if.then +if.then: ; preds = %entry + tail call void bitcast (void (...)* @foo1 to void ()*)() + br label %if.end + +if.else: ; preds = %entry + tail call void bitcast (void (...)* @foo2 to void ()*)() + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + +define void @test_zext_zero(i16 zeroext %x) optsize { +;CHECK-LABEL: test_zext_zero +entry: + %tobool = icmp eq i16 %x, 0 + br i1 %tobool, label %if.else, label %if.then +;CHECK-NOT: movw {{.*}}, #65535 +;CHECK: cbz r0, +if.then: ; preds = %entry + tail call void bitcast (void (...)* @foo1 to void ()*)() + br label %if.end + +if.else: ; preds = %entry + tail call void bitcast (void (...)* @foo2 to void ()*)() + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + + +declare void @foo1(...) +declare void @foo2(...) + + diff --git a/llvm/test/CodeGen/PowerPC/ppc-shrink-wrapping.ll b/llvm/test/CodeGen/PowerPC/ppc-shrink-wrapping.ll index 3dcb0b2..387c5f6 100644 --- a/llvm/test/CodeGen/PowerPC/ppc-shrink-wrapping.ll +++ b/llvm/test/CodeGen/PowerPC/ppc-shrink-wrapping.ll @@ -493,7 +493,7 @@ declare i32 @someVariadicFunc(i32, ...) ; CHECK-LABEL: noreturn: ; DISABLE: mflr {{[0-9]+}} ; -; CHECK: cmplwi 3, 0 +; CHECK: cmplwi 0, 3, 0 ; CHECK-NEXT: bne{{[-]?}} 0, .[[ABORT:LBB[0-9_]+]] ; ; CHECK: li 3, 42 diff --git a/llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll b/llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll index fb4ee8d..8ec339c 100644 --- a/llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll +++ b/llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll @@ -571,8 +571,7 @@ declare i32 @someVariadicFunc(i32, ...) ; CHECK-LABEL: noreturn: ; DISABLE: push ; -; CHECK: movs [[TMP:r[0-9]+]], #255 -; CHECK-NEXT: tst r0, [[TMP]] +; CHECK: cmp r0, #0 ; CHECK-NEXT: bne [[ABORT:LBB[0-9_]+]] ; ; CHECK: movs r0, #42 -- 2.7.4