[llvm-bugs] [Bug 44949] New: SROA and LVI interpreting undef differently

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Feb 18 08:42:26 PST 2020


https://bugs.llvm.org/show_bug.cgi?id=44949

            Bug ID: 44949
           Summary: SROA and LVI interpreting undef differently
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: Global Analyses
          Assignee: unassignedbugs at nondot.org
          Reporter: wmi at google.com
                CC: llvm-bugs at lists.llvm.org

Created attachment 23135
  --> https://bugs.llvm.org/attachment.cgi?id=23135&action=edit
test1.ll before SROA

I see some problem which I think is caused by the fact that SROA and LVI
interpret “undef” differently.

I attached the IR before SROA in test1.ll, after SROA in test2.ll and the IR
after CVP in test3.ll (which utilizes LVI):
opt -sroa -S test1.ll > test2.ll
opt -correlated-propagation -S test2.ll > test3.ll

In test2.ll after SROA:
_ZNKSt3__u12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5c_strEv.exit34:
  …
while.cond:
  %ref.tmp.sroa.79.0 = phi i64 [ undef,
%_ZNKSt3__u12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5c_strEv.exit34
], [ %ref.tmp.sroa.79.23.insert.mask15,
%_ZNSt3__u12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED2Ev.exit ]
.sroa.79.23.insert.mask15,
%_ZNSt3__u12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED2Ev.exit ]
  …
cleanup.thread.i63:                               ; preds = %if.end
  %ref.tmp.sroa.79.0..sroa_idx11 = getelementptr inbounds
%"class.std::__u::basic_string", %"class.std::__u::basic_string"* %result.i61,
i64 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 2
  %ref.tmp.sroa.79.0.copyload = load i64, i64* %ref.tmp.sroa.79.0..sroa_idx11,
align 8
  …
cleanup.i71:                                      ; preds = %if.end
  %ref.tmp.sroa.79.23.insert.mask = and i64 %ref.tmp.sroa.79.0,
72057594037927935
   …
if.then.i.i75:                                    ; preds = %cleanup.i71
   …
ReadLink.exit76:                                  ; preds = %if.then.i.i75,
%cleanup.i71, %cleanup.thread.i63
  %ref.tmp.sroa.79.1 = phi i64 [ %ref.tmp.sroa.79.0.copyload,
%cleanup.thread.i63 ], [ %ref.tmp.sroa.79.23.insert.mask, %if.then.i.i75 ], [
%ref.tmp.sroa.79.23.insert.mask, %cleanup.i71 ]
  …
_ZNSt3__u12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_.exit: ;
preds = %if.then.i.i83, %ReadLink.exit76
  %ref.tmp.sroa.79.0..sroa_idx12 = getelementptr inbounds
%"class.std::__u::basic_string", %"class.std::__u::basic_string"* %target, i64
0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 2
  store i64 %ref.tmp.sroa.79.1, i64* %ref.tmp.sroa.79.0..sroa_idx12, align 8
  %ref.tmp.sroa.79.23.insert.mask15 = and i64 %ref.tmp.sroa.79.1,
72057594037927935
  …
  br label %while.cond


%ref.tmp.sroa.79.0 is initialized to undef before the while loop in SROA
because no matter what value it has, its upper 8bits will be zero out in block
%cleanup.i71 anyway before stored into %target in block
_ZNSt3__u12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_.exit, so
%target’s corresponding bits will always be zeroed out if %cleanup.i71 is taken
and those bits zeroed out in %target are what the program cares about. 

In LVI called by CVP,   for the phi in while.cond:
%ref.tmp.sroa.79.0 = phi i64 [ undef,
%_ZNKSt3__u12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE5c_strEv.exit34
], [ %ref.tmp.sroa.79.23.insert.mask15,
%_ZNSt3__u12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED2Ev.exit ]

LVI thinks %ref.tmp.sroa.79.23.insert.mask15 is a contant range [0 ~
0x100000000000000) which is correct because  “%ref.tmp.sroa.79.23.insert.mask15
= and i64 %ref.tmp.sroa.79.1, 72057594037927935” in block
%_ZNSt3__u12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_.exit,
another phi operand is undef, so LVI thinks %ref.tmp.sroa.79.0 is a constant
range [0 ~ 0x100000000000000) too, and remove the instruction
“%ref.tmp.sroa.79.23.insert.mask = and i64 %ref.tmp.sroa.79.0,
72057594037927935” in cleanup.i71 (72057594037927935 is 0xffffffffffffff).
This.causes an intermittent error because now the related bits in target won’t
be zeroed out anymore in the first iteration of the while loop.

The problem is the undef inserted by SROA is meaningful only when the
instruction “%ref.tmp.sroa.79.23.insert.mask = and i64 %ref.tmp.sroa.79.0”,
72057594037927935” is in place in block %cleanup.i71. However, LVI understands
the undef literally to be any value, so it can assume it to be value “0” and
the instruction “%ref.tmp.sroa.79.23.insert.mask = and i64 %ref.tmp.sroa.79.0”
is of no use. 

I didn’t find similar case described in
https://www.cs.utah.edu/~regehr/papers/undef-pldi17.pdf. is it something wrong
in my understanding of the problem or is it a new case related with undef bug?

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200218/1d249f8b/attachment.html>


More information about the llvm-bugs mailing list