Previously SDNodeFlags::instersectWith(Flags) would do nothing if Flags was in an undefined state, which is very bad given that this is the default when getNode() is called without passing an explicit SDNodeFlags argument. This meant that if an already existing and reused node had a flag which the second caller to getNode() did not set, that flag would remain uncleared. This was exposed by https://bugs.llvm.org/show_bug.cgi?id=47092, where an NSW flag was incorrectly set on an add instruction (which did in fact overflow in one of the two original contexts), so when SystemZElimCompare removed the compare with 0 trusting that flag, wrong-code resulted. There is more that needs to be done in this area as discussed here: Differential Revision: https://reviews.llvm.org/D86871 Review: Ulrich Weigand, Sanjay Patel
30 lines
915 B
LLVM
30 lines
915 B
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
|
|
;
|
|
; Test that DAGCombiner properly clears the NUW/NSW flags on the memoized add
|
|
; node.
|
|
|
|
define void @fun(i64* %Src, i32* %Dst) {
|
|
; CHECK-LABEL: fun:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: iilf %r0, 1303940520
|
|
; CHECK-NEXT: n %r0, 4(%r2)
|
|
; CHECK-NEXT: lr %r1, %r0
|
|
; CHECK-NEXT: afi %r1, 1628135358
|
|
; CHECK-NEXT: locrnhe %r1, %r0
|
|
; CHECK-NEXT: st %r1, 0(%r3)
|
|
; CHECK-NEXT: br %r14
|
|
entry:
|
|
%0 = load i64, i64* %Src, align 8
|
|
%1 = trunc i64 %0 to i32
|
|
%conv = and i32 %1, 1303940520
|
|
%xor11.i = or i32 %conv, -2147483648
|
|
%xor2.i = add i32 %xor11.i, -519348290
|
|
%cmp.i = icmp slt i32 %xor2.i, 0
|
|
%sub3.i = add nuw nsw i32 %conv, 1628135358
|
|
%cond.i = select i1 %cmp.i, i32 %conv, i32 %sub3.i
|
|
store i32 %cond.i, i32* %Dst
|
|
ret void
|
|
}
|
|
|