[llvm] r334049 - [CodeGenPrepare] Move Extension Instructions Through Logical And Shift Instructions
Guozhi Wei via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 5 14:03:53 PDT 2018
Author: carrot
Date: Tue Jun 5 14:03:52 2018
New Revision: 334049
URL: http://llvm.org/viewvc/llvm-project?rev=334049&view=rev
Log:
[CodeGenPrepare] Move Extension Instructions Through Logical And Shift Instructions
CodeGenPrepare pass move extension instructions close to load instructions in different BB, so they can be combined later. But the extension instructions can't move through logical and shift instructions in current implementation. This patch enables this enhancement, so we can eliminate more extension instructions.
Differential Revision: https://reviews.llvm.org/D45537
This is re-commit of r331783, which was reverted by r333305. The performance regression was caused by some unlucky alignment, not a code generation problem.
Added:
llvm/trunk/test/Transforms/CodeGenPrepare/X86/ext-logicop.ll
- copied unchanged from r333304, llvm/trunk/test/Transforms/CodeGenPrepare/X86/ext-logicop.ll
Modified:
llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
llvm/trunk/test/CodeGen/X86/cmov.ll
llvm/trunk/test/CodeGen/X86/ins_subreg_coalesce-1.ll
llvm/trunk/test/CodeGen/X86/zext-logicop-shift-load.ll
Modified: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=334049&r1=334048&r2=334049&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp Tue Jun 5 14:03:52 2018
@@ -3390,6 +3390,47 @@ bool TypePromotionHelper::canGetThrough(
(IsSExt && BinOp->hasNoSignedWrap())))
return true;
+ // ext(and(opnd, cst)) --> and(ext(opnd), ext(cst))
+ if ((Inst->getOpcode() == Instruction::And ||
+ Inst->getOpcode() == Instruction::Or))
+ return true;
+
+ // ext(xor(opnd, cst)) --> xor(ext(opnd), ext(cst))
+ if (Inst->getOpcode() == Instruction::Xor) {
+ const ConstantInt *Cst = dyn_cast<ConstantInt>(Inst->getOperand(1));
+ // Make sure it is not a NOT.
+ if (Cst && !Cst->getValue().isAllOnesValue())
+ return true;
+ }
+
+ // zext(shrl(opnd, cst)) --> shrl(zext(opnd), zext(cst))
+ // It may change a poisoned value into a regular value, like
+ // zext i32 (shrl i8 %val, 12) --> shrl i32 (zext i8 %val), 12
+ // poisoned value regular value
+ // It should be OK since undef covers valid value.
+ if (Inst->getOpcode() == Instruction::LShr && !IsSExt)
+ return true;
+
+ // and(ext(shl(opnd, cst)), cst) --> and(shl(ext(opnd), ext(cst)), cst)
+ // It may change a poisoned value into a regular value, like
+ // zext i32 (shl i8 %val, 12) --> shl i32 (zext i8 %val), 12
+ // poisoned value regular value
+ // It should be OK since undef covers valid value.
+ if (Inst->getOpcode() == Instruction::Shl && Inst->hasOneUse()) {
+ const Instruction *ExtInst =
+ dyn_cast<const Instruction>(*Inst->user_begin());
+ if (ExtInst->hasOneUse()) {
+ const Instruction *AndInst =
+ dyn_cast<const Instruction>(*ExtInst->user_begin());
+ if (AndInst && AndInst->getOpcode() == Instruction::And) {
+ const ConstantInt *Cst = dyn_cast<ConstantInt>(AndInst->getOperand(1));
+ if (Cst &&
+ Cst->getValue().isIntN(Inst->getType()->getIntegerBitWidth()))
+ return true;
+ }
+ }
+ }
+
// Check if we can do the following simplification.
// ext(trunc(opnd)) --> ext(opnd)
if (!isa<TruncInst>(Inst))
Modified: llvm/trunk/test/CodeGen/X86/cmov.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/cmov.ll?rev=334049&r1=334048&r2=334049&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/cmov.ll (original)
+++ llvm/trunk/test/CodeGen/X86/cmov.ll Tue Jun 5 14:03:52 2018
@@ -79,9 +79,8 @@ define i1 @test4() nounwind {
; CHECK-LABEL: test4:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movsbl {{.*}}(%rip), %edx
-; CHECK-NEXT: movl %edx, %eax
-; CHECK-NEXT: shrb $7, %al
-; CHECK-NEXT: movzbl %al, %ecx
+; CHECK-NEXT: movzbl %dl, %ecx
+; CHECK-NEXT: shrl $7, %ecx
; CHECK-NEXT: xorl $1, %ecx
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: sarl %cl, %edx
Modified: llvm/trunk/test/CodeGen/X86/ins_subreg_coalesce-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/ins_subreg_coalesce-1.ll?rev=334049&r1=334048&r2=334049&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/ins_subreg_coalesce-1.ll (original)
+++ llvm/trunk/test/CodeGen/X86/ins_subreg_coalesce-1.ll Tue Jun 5 14:03:52 2018
@@ -4,7 +4,7 @@
define fastcc i32 @t() nounwind {
; CHECK-LABEL: t:
; CHECK: # %bb.0: # %walkExprTree.exit
-; CHECK-NEXT: movl 0, %eax
+; CHECK-NEXT: movzwl 0, %eax
; CHECK-NEXT: orl $2, %eax
; CHECK-NEXT: movw %ax, 0
; CHECK-NEXT: shrl $3, %eax
Modified: llvm/trunk/test/CodeGen/X86/zext-logicop-shift-load.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/zext-logicop-shift-load.ll?rev=334049&r1=334048&r2=334049&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/zext-logicop-shift-load.ll (original)
+++ llvm/trunk/test/CodeGen/X86/zext-logicop-shift-load.ll Tue Jun 5 14:03:52 2018
@@ -88,22 +88,6 @@ entry:
ret i64 %1
}
-; Don't do the folding if the other operand isn't a constant.
-define i64 @test7(i8* %data, i8 %logop) {
-; CHECK-LABEL: test7:
-; CHECK: movb
-; CHECK-NEXT: shrb
-; CHECK-NEXT: orb
-; CHECK-NEXT: movzbl
-; CHECK-NEXT: retq
-entry:
- %bf.load = load i8, i8* %data, align 4
- %bf.clear = lshr i8 %bf.load, 2
- %0 = or i8 %bf.clear, %logop
- %1 = zext i8 %0 to i64
- ret i64 %1
-}
-
; Load is folded with sext.
define i64 @test8(i8* %data) {
; CHECK-LABEL: test8:
More information about the llvm-commits
mailing list