[PATCH] D40304: [InstCombine] PR35354: Convert load bitcast (select (Cond, &V1, &V2)) --> select(Cond, load bitcast &V1, load bitcast &V2)

Alexey Bataev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 21 07:06:23 PST 2017


ABataev created this revision.

If we have the code like this:

  float a, b;
  a = std::max(a ,b);

it is converted into something like this:

  %call = call dereferenceable(4) float* @_ZSt3maxIfERKT_S2_S2_(float* nonnull dereferenceable(4) %a.addr, float* nonnull dereferenceable(4) %b.addr)
  %1 = bitcast float* %call to i32*
  %2 = load i32, i32* %1, align 4
  %3 = bitcast float* %a.addr to i32*
  store i32 %2, i32* %3, align 4

After inlinning this code is converted to the next:

  %1 = load float, float* %a.addr
  %2 = load float, float* %b.addr
  %cmp.i = fcmp fast olt float %1, %2
  %__b.__a.i = select i1 %cmp.i, float* %a.addr, float* %b.addr
  %3 = bitcast float* %__b.__a.i to i32*
  %4 = load i32, i32* %3, align 4
  %5 = bitcast float* %arrayidx to i32*
  store i32 %4, i32* %5, align 4

This pattern is not recognized as minmax pattern.
Patch solves this problem by converting sequence

  load bitcast (select (Cond, &V1, &V2))

to a sequence

  select(Cond, load bitcast &V1, load bitcast &V2)

After this the code is recognized as minmax pattern.


https://reviews.llvm.org/D40304

Files:
  lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  test/Transforms/InstCombine/load-bitcast-select.ll


Index: test/Transforms/InstCombine/load-bitcast-select.ll
===================================================================
--- test/Transforms/InstCombine/load-bitcast-select.ll
+++ test/Transforms/InstCombine/load-bitcast-select.ll
@@ -21,11 +21,8 @@
 ; CHECK-NEXT:    [[TMP1:%.*]] = load float, float* [[ARRAYIDX]], align 4
 ; CHECK-NEXT:    [[TMP2:%.*]] = load float, float* [[ARRAYIDX2]], align 4
 ; CHECK-NEXT:    [[CMP_I:%.*]] = fcmp fast olt float [[TMP1]], [[TMP2]]
-; CHECK-NEXT:    [[__B___A_I:%.*]] = select i1 [[CMP_I]], float* [[ARRAYIDX2]], float* [[ARRAYIDX]]
-; CHECK-NEXT:    [[TMP3:%.*]] = bitcast float* [[__B___A_I]] to i32*
-; CHECK-NEXT:    [[TMP4:%.*]] = load i32, i32* [[TMP3]], align 4
-; CHECK-NEXT:    [[TMP5:%.*]] = bitcast float* [[ARRAYIDX]] to i32*
-; CHECK-NEXT:    store i32 [[TMP4]], i32* [[TMP5]], align 4
+; CHECK-NEXT:    [[DOTV:%.*]] = select i1 [[CMP_I]], float [[TMP2]], float [[TMP1]]
+; CHECK-NEXT:    store float [[DOTV]], float* [[ARRAYIDX]], align 4
 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_0]], 1
 ; CHECK-NEXT:    br label [[FOR_COND]]
 ;
Index: lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -24,6 +24,7 @@
 #include "llvm/IR/MDBuilder.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/LoopUtils.h"
 using namespace llvm;
 
 #define DEBUG_TYPE "instcombine"
@@ -1015,15 +1016,29 @@
     // but it would not be valid if we transformed it to load from null
     // unconditionally.
     //
+    // load bitcast (select (Cond, &V1, &V2))  --> select(Cond, load bitcast
+    // &V1, load bitcast &V2).
+    auto *BC = dyn_cast<BitCastInst>(Op);
+    if (BC)
+      Op = BC->getOperand(0);
+
     if (SelectInst *SI = dyn_cast<SelectInst>(Op)) {
       // load (select (Cond, &V1, &V2))  --> select(Cond, load &V1, load &V2).
       unsigned Align = LI.getAlignment();
       if (isSafeToLoadUnconditionally(SI->getOperand(1), Align, DL, SI) &&
           isSafeToLoadUnconditionally(SI->getOperand(2), Align, DL, SI)) {
-        LoadInst *V1 = Builder.CreateLoad(SI->getOperand(1),
-                                          SI->getOperand(1)->getName()+".val");
-        LoadInst *V2 = Builder.CreateLoad(SI->getOperand(2),
-                                          SI->getOperand(2)->getName()+".val");
+        Value *AddrLHS = SI->getOperand(1);
+        Value *AddrRHS = SI->getOperand(2);
+        if (BC) {
+          AddrLHS = Builder.CreateBitCast(AddrLHS, BC->getDestTy(),
+                                          AddrLHS->getName() + ".cast");
+          propagateIRFlags(AddrLHS, BC);
+          AddrRHS = Builder.CreateBitCast(AddrRHS, BC->getDestTy(),
+                                          AddrRHS->getName() + ".cast");
+          propagateIRFlags(AddrRHS, BC);
+        }
+        LoadInst *V1 = Builder.CreateLoad(AddrLHS, AddrLHS->getName() + ".val");
+        LoadInst *V2 = Builder.CreateLoad(AddrRHS, AddrRHS->getName() + ".val");
         assert(LI.isUnordered() && "implied by above");
         V1->setAlignment(Align);
         V1->setAtomic(LI.getOrdering(), LI.getSyncScopeID());
@@ -1035,14 +1050,26 @@
       // load (select (cond, null, P)) -> load P
       if (isa<ConstantPointerNull>(SI->getOperand(1)) &&
           LI.getPointerAddressSpace() == 0) {
-        LI.setOperand(0, SI->getOperand(2));
+        Value *Operand = SI->getOperand(2);
+        if (BC) {
+          Operand = Builder.CreateBitCast(Operand, BC->getDestTy(),
+                                          Operand->getName() + ".cast");
+          propagateIRFlags(Operand, BC);
+        }
+        LI.setOperand(0, Operand);
         return &LI;
       }
 
       // load (select (cond, P, null)) -> load P
       if (isa<ConstantPointerNull>(SI->getOperand(2)) &&
           LI.getPointerAddressSpace() == 0) {
-        LI.setOperand(0, SI->getOperand(1));
+        Value *Operand = SI->getOperand(1);
+        if (BC) {
+          Operand = Builder.CreateBitCast(Operand, BC->getDestTy(),
+                                          Operand->getName() + ".cast");
+          propagateIRFlags(Operand, BC);
+        }
+        LI.setOperand(0, Operand);
         return &LI;
       }
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D40304.123785.patch
Type: text/x-patch
Size: 4441 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171121/26a38d50/attachment.bin>


More information about the llvm-commits mailing list