/// Original Address.
Value *Original;
+ /// Common value among addresses
+ Value *CommonValue = nullptr;
+
public:
AddressingModeCombiner(const SimplifyQuery &_SQ, Value *OriginalValue)
: SQ(_SQ), Original(OriginalValue) {}
+ ~AddressingModeCombiner() { eraseCommonValueIfDead(); }
+
/// Get the combined AddrMode
const ExtAddrMode &getAddrMode() const { return AddrModes[0]; }
if (!initializeMap(Map))
return false;
- Value *CommonValue = findCommon(Map);
+ CommonValue = findCommon(Map);
if (CommonValue)
AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes);
return CommonValue != nullptr;
}
private:
+ /// `CommonValue` may be a placeholder inserted by us.
+ /// If the placeholder is not used, we should remove this dead instruction.
+ void eraseCommonValueIfDead() {
+ if (CommonValue && CommonValue->getNumUses() == 0)
+ if (Instruction *CommonInst = dyn_cast<Instruction>(CommonValue))
+ CommonInst->eraseFromParent();
+ }
+
/// Initialize Map with anchor values. For address seen
/// we set the value of different field saw in this address.
/// At the same time we find a common type for different field we will
--- /dev/null
+; RUN: opt -codegenprepare -mtriple=x86_64 %s -S -o - | FileCheck %s
+; RUN: opt -codegenprepare -mtriple=i386 %s -S -o - | FileCheck %s
+
+define i32 @f(i32 %0) {
+; CHECK-LABEL: @f
+; CHECK: BB:
+; CHECK: %P0 = alloca i32, i32 8, align 4
+; CHECK: %P1 = getelementptr i32, ptr %P0, i32 1
+; CHECK: %1 = icmp eq i32 %0, 0
+; CHECK: %P2 = getelementptr i1, ptr %P1, i1 %1
+; CHECK: %2 = icmp eq i32 %0, 0
+; CHECK: %P3 = select i1 %2, ptr %P1, ptr %P2
+; CHECK: %L1 = load i32, ptr %P3, align 4
+; CHECK: ret i32 %L1
+BB:
+ %P0 = alloca i32, i32 8
+ %P1 = getelementptr i32, ptr %P0, i32 1
+ %B0 = icmp eq i32 %0, 0
+ br label %BB1
+
+BB1: ; preds = %BB1, %BB
+ %P2 = getelementptr i1, ptr %P1, i1 %B0
+ br i1 false, label %BB1, label %BB2
+
+BB2: ; preds = %BB1
+ %P3 = select i1 %B0, ptr %P1, ptr %P2
+ %L1 = load i32, ptr %P3
+ ret i32 %L1
+}