mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
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
This commit is contained in:
parent
6c79566863
commit
6d90b40b86
@ -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<VTSDNode>(OpL->getOperand(1))->getVT() == NewLHS.getValueType() &&
|
||||
OpR->getOpcode() == ISD::AssertSext &&
|
||||
cast<VTSDNode>(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 {
|
||||
|
@ -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
|
||||
;
|
||||
|
@ -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
|
||||
;
|
||||
|
105
test/CodeGen/ARM/no_redundant_trunc_for_cmp.ll
Normal file
105
test/CodeGen/ARM/no_redundant_trunc_for_cmp.ll
Normal file
@ -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(...)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user