Craig Topper d9962c400f
[IR] Add disjoint flag for Or instructions. (#72583)
This flag indicates that every bit is known to be zero in at least one
of the inputs. This allows the Or to be treated as an Add since there is
no possibility of a carry from any bit.

If the flag is present and this property does not hold, the result is
poison.

This makes it easier to reverse the InstCombine transform that turns Add
into Or.

This is inspired by a comment here
https://github.com/llvm/llvm-project/pull/71955#discussion_r1391614578

Discourse thread
https://discourse.llvm.org/t/rfc-add-or-disjoint-flag/75036
2023-11-24 08:49:19 -08:00

37 lines
1.3 KiB
LLVM

; RUN: llvm-as < %s | llvm-dis > %t0
; RUN: opt -S < %s > %t1
; RUN: diff %t0 %t1
; RUN: verify-uselistorder < %s
; PR6140
; Make sure the flags are serialized/deserialized properly for both
; forward and backward references.
define void @foo() nounwind {
entry:
br label %first
second: ; preds = %first
%u = add nuw i32 %a, 0 ; <i32> [#uses=0]
%s = add nsw i32 %a, 0 ; <i32> [#uses=0]
%us = add nuw nsw i32 %a, 0 ; <i32> [#uses=0]
%z = add i32 %a, 0 ; <i32> [#uses=0]
%hh = zext nneg i32 %a to i64
%ll = zext i32 %s to i64
%jj = or disjoint i32 %a, 0
%oo = or i32 %a, 0
unreachable
first: ; preds = %entry
%a = bitcast i32 0 to i32 ; <i32> [#uses=8]
%uu = add nuw i32 %a, 0 ; <i32> [#uses=0]
%ss = add nsw i32 %a, 0 ; <i32> [#uses=0]
%uuss = add nuw nsw i32 %a, 0 ; <i32> [#uses=0]
%zz = add i32 %a, 0 ; <i32> [#uses=0]
%kk = zext nneg i32 %a to i64
%rr = zext i32 %ss to i64
%mm = or disjoint i32 %a, 0
%nn = or i32 %a, 0
br label %second
}