[PATCH] D94851: [InstCombine] Don't transform (select c, ext(TI), ext(FI)) if ext is free

Guozhi Wei via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 15 18:04:11 PST 2021


Carrot created this revision.
Herald added subscribers: pengfei, hiraditya.
Carrot requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Function InstCombinerImpl::foldSelectOpOp can do following transformation

  (select c, ext(TI), ext(FI))  ==> (ext(select c, TI, FI))

If TI and FI are load, then ext is free on x86, in this situation we should not move ext out of select.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D94851

Files:
  llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
  llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
  llvm/test/Transforms/InstCombine/select-ext.ll


Index: llvm/test/Transforms/InstCombine/select-ext.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/select-ext.ll
@@ -0,0 +1,22 @@
+; RUN: opt -instcombine -mtriple=x86_64-unknown-unknown -S < %s | FileCheck %s
+
+; If zext has 0 cost, it should not be moved after select.
+
+; CHECK-LABEL: @foo
+; CHECK:        [[LD1:%.*]] = load volatile i8, i8* [[PTR1:%.*]]
+; CHECK:        [[CONV1:%.*]] = zext i8 [[LD1]] to i64
+; CHECK:        [[LD2:%.*]] = load volatile i8, i8* [[PTR2:%.*]]
+; CHECK:        [[CONV2:%.*]] = zext i8 [[LD2]] to i64
+; CHECK:        [[RESULT:%.*]] = select i1 [[COND:%.*]], i64 [[CONV2]], i64 [[CONV1]]
+; CHECK:        ret i64 [[RESULT]]
+
+define i64 @foo(i8* %p, i1 zeroext %c) {
+  %ld1 = load volatile i8, i8* %p
+  %conv = zext i8 %ld1 to i64
+  %arrayidx1 = getelementptr inbounds i8, i8* %p, i64 1
+  %ld2 = load volatile i8, i8* %arrayidx1
+  %conv2 = zext i8 %ld2 to i64
+  %cond = select i1 %c, i64 %conv2, i64 %conv
+  ret i64 %cond
+}
+
Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -18,6 +18,7 @@
 #include "llvm/Analysis/AssumptionCache.h"
 #include "llvm/Analysis/CmpInstAnalysis.h"
 #include "llvm/Analysis/InstructionSimplify.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Constant.h"
@@ -311,6 +312,14 @@
       return nullptr;
     }
 
+    // If both cast instructions are free, don't merge them.
+    auto Opcode = TI->getOpcode();
+    if (TTI.getCastInstrCost(Opcode, TI->getType(), FIOpndTy,
+                             TTI.getCastContextHint(TI)) == 0 &&
+        TTI.getCastInstrCost(Opcode, FI->getType(), FIOpndTy,
+                             TTI.getCastContextHint(FI)) == 0)
+      return nullptr;
+
     // Fold this by inserting a select from the input values.
     Value *NewSI =
         Builder.CreateSelect(Cond, TI->getOperand(0), FI->getOperand(0),
Index: llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
===================================================================
--- llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
+++ llvm/include/llvm/Transforms/InstCombine/InstCombiner.h
@@ -43,6 +43,7 @@
 /// This class provides both the logic to recursively visit instructions and
 /// combine them.
 class LLVM_LIBRARY_VISIBILITY InstCombiner {
+protected:
   /// Only used to call target specific inst combining.
   TargetTransformInfo &TTI;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D94851.317131.patch
Type: text/x-patch
Size: 2701 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210116/9c9f3809/attachment.bin>


More information about the llvm-commits mailing list