[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