[llvm] r322930 - [InstCombine] Make foldSelectOpOp able to handle two-operand getelementptr
John Brawn via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 19 02:05:15 PST 2018
Author: john.brawn
Date: Fri Jan 19 02:05:15 2018
New Revision: 322930
URL: http://llvm.org/viewvc/llvm-project?rev=322930&view=rev
Log:
[InstCombine] Make foldSelectOpOp able to handle two-operand getelementptr
Three (or more) operand getelementptrs could plausibly also be handled, but
handling only two-operand fits in easily with the existing BinaryOperator
handling.
Differential Revision: https://reviews.llvm.org/D39958
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
llvm/trunk/test/Transforms/InstCombine/select-gep.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=322930&r1=322929&r2=322930&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Fri Jan 19 02:05:15 2018
@@ -300,12 +300,13 @@ Instruction *InstCombiner::foldSelectOpO
TI->getType());
}
- // Only handle binary operators with one-use here. As with the cast case
- // above, it may be possible to relax the one-use constraint, but that needs
- // be examined carefully since it may not reduce the total number of
- // instructions.
- BinaryOperator *BO = dyn_cast<BinaryOperator>(TI);
- if (!BO || !TI->hasOneUse() || !FI->hasOneUse())
+ // Only handle binary operators (including two-operand getelementptr) with
+ // one-use here. As with the cast case above, it may be possible to relax the
+ // one-use constraint, but that needs be examined carefully since it may not
+ // reduce the total number of instructions.
+ if (TI->getNumOperands() != 2 || FI->getNumOperands() != 2 ||
+ (!isa<BinaryOperator>(TI) && !isa<GetElementPtrInst>(TI)) ||
+ !TI->hasOneUse() || !FI->hasOneUse())
return nullptr;
// Figure out if the operations have any operands in common.
@@ -342,7 +343,18 @@ Instruction *InstCombiner::foldSelectOpO
SI.getName() + ".v", &SI);
Value *Op0 = MatchIsOpZero ? MatchOp : NewSI;
Value *Op1 = MatchIsOpZero ? NewSI : MatchOp;
- return BinaryOperator::Create(BO->getOpcode(), Op0, Op1);
+ if (auto *BO = dyn_cast<BinaryOperator>(TI)) {
+ return BinaryOperator::Create(BO->getOpcode(), Op0, Op1);
+ }
+ if (auto *TGEP = dyn_cast<GetElementPtrInst>(TI)) {
+ auto *FGEP = cast<GetElementPtrInst>(FI);
+ Type *ElementType = TGEP->getResultElementType();
+ return TGEP->isInBounds() && FGEP->isInBounds()
+ ? GetElementPtrInst::CreateInBounds(ElementType, Op0, {Op1})
+ : GetElementPtrInst::Create(ElementType, Op0, {Op1});
+ }
+ llvm_unreachable("Expected BinaryOperator or GEP");
+ return nullptr;
}
static bool isSelect01(const APInt &C1I, const APInt &C2I) {
Modified: llvm/trunk/test/Transforms/InstCombine/select-gep.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select-gep.ll?rev=322930&r1=322929&r2=322930&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/select-gep.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/select-gep.ll Fri Jan 19 02:05:15 2018
@@ -3,10 +3,9 @@
define i32* @test1a(i32* %p, i32* %q) {
; CHECK-LABEL: @test1a(
-; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 4
-; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i32, i32* [[Q:%.*]], i64 4
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32* [[P]], [[Q]]
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32* [[GEP1]], i32* [[GEP2]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32* [[P:%.*]], [[Q:%.*]]
+; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], i32* [[P]], i32* [[Q]]
+; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i32, i32* [[SELECT_V]], i64 4
; CHECK-NEXT: ret i32* [[SELECT]]
;
%gep1 = getelementptr i32, i32* %p, i64 4
@@ -18,10 +17,9 @@ define i32* @test1a(i32* %p, i32* %q) {
define i32* @test1b(i32* %p, i32* %q) {
; CHECK-LABEL: @test1b(
-; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 4
-; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i32, i32* [[Q:%.*]], i64 4
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32* [[P]], [[Q]]
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32* [[GEP1]], i32* [[GEP2]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32* [[P:%.*]], [[Q:%.*]]
+; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], i32* [[P]], i32* [[Q]]
+; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i32, i32* [[SELECT_V]], i64 4
; CHECK-NEXT: ret i32* [[SELECT]]
;
%gep1 = getelementptr inbounds i32, i32* %p, i64 4
@@ -33,10 +31,9 @@ define i32* @test1b(i32* %p, i32* %q) {
define i32* @test1c(i32* %p, i32* %q) {
; CHECK-LABEL: @test1c(
-; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 4
-; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, i32* [[Q:%.*]], i64 4
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32* [[P]], [[Q]]
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32* [[GEP1]], i32* [[GEP2]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32* [[P:%.*]], [[Q:%.*]]
+; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], i32* [[P]], i32* [[Q]]
+; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i32, i32* [[SELECT_V]], i64 4
; CHECK-NEXT: ret i32* [[SELECT]]
;
%gep1 = getelementptr i32, i32* %p, i64 4
@@ -48,10 +45,9 @@ define i32* @test1c(i32* %p, i32* %q) {
define i32* @test1d(i32* %p, i32* %q) {
; CHECK-LABEL: @test1d(
-; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 4
-; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, i32* [[Q:%.*]], i64 4
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32* [[P]], [[Q]]
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32* [[GEP1]], i32* [[GEP2]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32* [[P:%.*]], [[Q:%.*]]
+; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], i32* [[P]], i32* [[Q]]
+; CHECK-NEXT: [[SELECT:%.*]] = getelementptr inbounds i32, i32* [[SELECT_V]], i64 4
; CHECK-NEXT: ret i32* [[SELECT]]
;
%gep1 = getelementptr inbounds i32, i32* %p, i64 4
@@ -63,10 +59,9 @@ define i32* @test1d(i32* %p, i32* %q) {
define i32* @test2(i32* %p, i64 %x, i64 %y) {
; CHECK-LABEL: @test2(
-; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 [[X:%.*]]
-; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 [[Y:%.*]]
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X]], [[Y]]
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32* [[GEP1]], i32* [[GEP2]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], i64 [[X]], i64 [[Y]]
+; CHECK-NEXT: [[SELECT:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 [[SELECT_V]]
; CHECK-NEXT: ret i32* [[SELECT]]
;
%gep1 = getelementptr inbounds i32, i32* %p, i64 %x
More information about the llvm-commits
mailing list