Index: lib/Target/ARM/ARMCodeGenPrepare.cpp =================================================================== --- lib/Target/ARM/ARMCodeGenPrepare.cpp +++ lib/Target/ARM/ARMCodeGenPrepare.cpp @@ -230,7 +230,7 @@ return false; if (isa(I) || isa(I) || isa(I) || - isa(I)) + isa(I) || isa(V)) return false; if (auto *ZExt = dyn_cast(I)) @@ -600,7 +600,9 @@ if (CurrentVisited.count(V)) continue; - if (!isa(V) && !isSource(V)) + // Ignore pointers and non-instructions, other than arguments. + if (isa(V->getType()) || + (!isa(V) && !isSource(V))) continue; // If we've already visited this value from somewhere, bail now because Index: test/CodeGen/ARM/arm-cgp-icmps.ll =================================================================== --- test/CodeGen/ARM/arm-cgp-icmps.ll +++ test/CodeGen/ARM/arm-cgp-icmps.ll @@ -466,3 +466,4 @@ exit: ret void } + Index: test/CodeGen/ARM/arm-cgp-phis-calls-ret.ll =================================================================== --- test/CodeGen/ARM/arm-cgp-phis-calls-ret.ll +++ test/CodeGen/ARM/arm-cgp-phis-calls-ret.ll @@ -87,6 +87,76 @@ ret void } +; CHECK-COMMON-LABEL: phi_pointers +; CHECK-COMMON-NOT: uxt +define void @phi_pointers(i16* %a, i16* %b, i8 zeroext %M, i8 zeroext %N) { +entry: + %add = add nuw i8 %M, 1 + %and = and i8 %add, 1 + %cmp = icmp ugt i8 %add, %N + %base = select i1 %cmp, i16* %a, i16* %b + %other = select i1 %cmp, i16* %b, i16* %b + br label %loop + +loop: + %ptr = phi i16* [ %base, %entry ], [ %gep, %loop ] + %idx = phi i8 [ %and, %entry ], [ %inc, %loop ] + %load = load i16, i16* %ptr, align 2 + %inc = add nuw nsw i8 %idx, 1 + %gep = getelementptr inbounds i16, i16* %ptr, i8 %inc + %cond = icmp eq i16* %gep, %other + br i1 %cond, label %exit, label %loop + +exit: + ret void +} + +; CHECK-COMMON-LABEL: phi_pointers_null +; CHECK-COMMON-NOT: uxt +define void @phi_pointers_null(i16* %a, i16* %b, i8 zeroext %M, i8 zeroext %N) { +entry: + %add = add nuw i8 %M, 1 + %and = and i8 %add, 1 + %cmp = icmp ugt i8 %add, %N + %base = select i1 %cmp, i16* %a, i16* %b + %other = select i1 %cmp, i16* %b, i16* %b + %cmp.1 = icmp eq i16* %base, %other + br i1 %cmp.1, label %fail, label %loop + +fail: + br label %loop + +loop: + %ptr = phi i16* [ %base, %entry ], [ null, %fail ], [ %gep, %if.then ] + %idx = phi i8 [ %and, %entry ], [ 0, %fail ], [ %inc, %if.then ] + %undef = icmp eq i16* %ptr, undef + br i1 %undef, label %exit, label %if.then + +if.then: + %load = load i16, i16* %ptr, align 2 + %inc = add nuw nsw i8 %idx, 1 + %gep = getelementptr inbounds i16, i16* %ptr, i8 %inc + %cond = icmp eq i16* %gep, %other + br i1 %cond, label %exit, label %loop + +exit: + ret void +} + +declare i8 @do_something_with_ptr(i8, i16*) + +; CHECK-COMMON-LABEL: call_pointer +; CHECK-COMMON-NOT: uxt +define i8 @call_pointer(i8 zeroext %x, i8 zeroext %y, i16* %a, i16* %b) { + %or = or i8 %x, %y + %shr = lshr i8 %or, 1 + %add = add nuw i8 %shr, 2 + %cmp = icmp ne i8 %add, 0 + %ptr = select i1 %cmp, i16* %a, i16* %b + %call = tail call zeroext i8 @do_something_with_ptr(i8 %shr, i16* %ptr) + ret i8 %call +} + ; Just check that phis also work with i16s. ; CHECK-COMMON-LABEL: phi_i16: ; CHECK-COMMON-NOT: uxt