return false;
assert((!MO.isDef() || RegDefs.count(MO.getReg())) &&
"All defs must be tracked in RegDefs by now!");
- return !MO.isDef() || RegDefs.find(MO.getReg())->second == MI;
+
+ if (!MO.isDef()) {
+ // FIXME: This is unnecessary, we should be able to
+ // assert(MO.isDef()) here.
+ return true;
+ }
+
+ for (unsigned Reg : RegUses)
+ if (TRI.regsOverlap(Reg, MO.getReg()))
+ return false; // We found a write-after-read
+
+ for (auto &OtherDef : RegDefs) {
+ unsigned OtherReg = OtherDef.first;
+ MachineInstr *OtherMI = OtherDef.second;
+ if (OtherMI != MI && TRI.regsOverlap(OtherReg, MO.getReg()))
+ return false;
+ }
+
+ return true;
};
if (!all_of(MI->operands(), IsMIOperandSafe))
ret i32 0
}
+ define i32 @dependency_live_in_hazard(i32* %ptr, i32** %ptr2, i32* %ptr3) #0 {
+ entry:
+ %val = load i32*, i32** %ptr2
+ %ptr_is_null = icmp eq i32* %ptr, null
+ br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
+
+ not_null: ; preds = %entry
+ %addend = load i32, i32* %val
+ %result = load i32, i32* %ptr
+ %result.shr = lshr i32 %result, 4
+ %result.and = and i32 %result.shr, 4095
+ %result.add = add i32 %addend, %result.and
+ ret i32 %result.add
+
+ is_null: ; preds = %entry
+ ret i32 0
+ }
+
+ attributes #0 = { "target-features"="+bmi,+bmi2" }
+
!0 = !{}
...
---
RETQ %eax
...
+---
+name: dependency_live_in_hazard
+# CHECK-LABEL: name: dependency_live_in_hazard
+# CHECK: bb.0.entry:
+# CHECK-NOT: FAULTING_LOAD_OP
+# CHECK: bb.1.not_null:
+
+# Make sure that the BEXTR32rm instruction below is not used to emit
+# an implicit null check -- hoisting it will require hosting the move
+# to %esi and we cannot do that without clobbering the use of %rsi in
+# the first instruction in bb.1.not_null.
+alignment: 4
+tracksRegLiveness: true
+liveins:
+ - { reg: '%rdi' }
+ - { reg: '%rsi' }
+body: |
+ bb.0.entry:
+ successors: %bb.2.is_null, %bb.1.not_null
+ liveins: %rdi, %rsi
+
+ TEST64rr %rdi, %rdi, implicit-def %eflags
+ JE_1 %bb.2.is_null, implicit killed %eflags
+
+ bb.1.not_null:
+ liveins: %rdi, %rsi
+
+ %rcx = MOV64rm killed %rsi, 1, _, 0, _ :: (load 8 from %ir.ptr2)
+ %esi = MOV32ri 3076
+ %eax = BEXTR32rm killed %rdi, 1, _, 0, _, killed %esi, implicit-def dead %eflags :: (load 4 from %ir.ptr)
+ %eax = ADD32rm killed %eax, killed %rcx, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.val)
+ RETQ %eax
+
+ bb.2.is_null:
+ %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
+ RETQ %eax
+
+...