I noticed this while reviewing the test diffs in D115460
(and so the diffs in that patch will be reduced if this one is applied first).
This is effectively a revert of
3436dc29239d ( https://reviews.llvm.org/rG3436dc29239d ) -
since that commit, we've made several enhancements, so the reasoning there is no longer
valid. Specifically, we added a poison value to IR, and we clarified the behavior of
undef/poison elements in a shuffle mask:
https://llvm.org/docs/LangRef.html#shufflevector-instruction
Alive2 seems to agree that the propagation of flags in the test diffs shown here are valid:
https://alive2.llvm.org/ce/z/UuY-jr
https://alive2.llvm.org/ce/z/GXoMD9
https://alive2.llvm.org/ce/z/nVCyVH
Differential Revision: https://reviews.llvm.org/D115526
simplifyAndSetOp(I, 0, DemandedElts, UndefElts);
simplifyAndSetOp(I, 1, DemandedElts, UndefElts2);
- // Any change to an instruction with potential poison must clear those flags
- // because we can not guarantee those constraints now. Other analysis may
- // determine that it is safe to re-apply the flags.
- if (MadeChange)
- BO->dropPoisonGeneratingFlags();
-
// Output elements are undefined if both are undefined. Consider things
// like undef & 0. The result is known zero, not undef.
UndefElts &= UndefElts2;
; CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP2]] to <2 x i64>
; CHECK-NEXT: [[TMP5:%.*]] = and <2 x i64> [[TMP3]], <i64 4294967295, i64 poison>
; CHECK-NEXT: [[TMP6:%.*]] = and <2 x i64> [[TMP4]], <i64 4294967295, i64 poison>
-; CHECK-NEXT: [[TMP7:%.*]] = mul <2 x i64> [[TMP5]], [[TMP6]]
+; CHECK-NEXT: [[TMP7:%.*]] = mul nuw <2 x i64> [[TMP5]], [[TMP6]]
; CHECK-NEXT: [[TMP8:%.*]] = shufflevector <2 x i64> [[TMP7]], <2 x i64> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: ret <2 x i64> [[TMP8]]
;
; CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i32> [[TMP2]] to <2 x i64>
; CHECK-NEXT: [[TMP5:%.*]] = and <2 x i64> [[TMP3]], <i64 4294967295, i64 poison>
; CHECK-NEXT: [[TMP6:%.*]] = and <2 x i64> [[TMP4]], <i64 4294967295, i64 poison>
-; CHECK-NEXT: [[TMP7:%.*]] = mul <2 x i64> [[TMP5]], [[TMP6]]
+; CHECK-NEXT: [[TMP7:%.*]] = mul nuw <2 x i64> [[TMP5]], [[TMP6]]
; CHECK-NEXT: [[TMP8:%.*]] = shufflevector <2 x i64> [[TMP7]], <2 x i64> undef, <2 x i32> zeroinitializer
; CHECK-NEXT: ret <2 x i64> [[TMP8]]
;
; CHECK-LABEL: @or_add_not_enough_masking(
; CHECK-NEXT: [[V0:%.*]] = lshr <4 x i8> [[V:%.*]], <i8 1, i8 1, i8 1, i8 1>
; CHECK-NEXT: [[T1:%.*]] = or <4 x i8> [[V0]], <i8 poison, i8 poison, i8 -64, i8 -64>
-; CHECK-NEXT: [[T2:%.*]] = add <4 x i8> [[V0]], <i8 1, i8 2, i8 poison, i8 poison>
+; CHECK-NEXT: [[T2:%.*]] = add nuw nsw <4 x i8> [[V0]], <i8 1, i8 2, i8 poison, i8 poison>
; CHECK-NEXT: [[T3:%.*]] = shufflevector <4 x i8> [[T2]], <4 x i8> [[T1]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
; CHECK-NEXT: ret <4 x i8> [[T3]]
;
; CHECK-LABEL: @or_add_not_enough_masking(
; CHECK-NEXT: [[V0:%.*]] = lshr <4 x i8> [[V:%.*]], <i8 1, i8 1, i8 1, i8 1>
; CHECK-NEXT: [[T1:%.*]] = or <4 x i8> [[V0]], <i8 poison, i8 poison, i8 -64, i8 -64>
-; CHECK-NEXT: [[T2:%.*]] = add <4 x i8> [[V0]], <i8 1, i8 2, i8 poison, i8 poison>
+; CHECK-NEXT: [[T2:%.*]] = add nuw nsw <4 x i8> [[V0]], <i8 1, i8 2, i8 poison, i8 poison>
; CHECK-NEXT: [[T3:%.*]] = shufflevector <4 x i8> [[T2]], <4 x i8> [[T1]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
; CHECK-NEXT: ret <4 x i8> [[T3]]
;
define <3 x i8> @shuf_add(<3 x i8> %x) {
; CHECK-LABEL: @shuf_add(
-; CHECK-NEXT: [[BO:%.*]] = add <3 x i8> [[X:%.*]], <i8 poison, i8 2, i8 3>
+; CHECK-NEXT: [[BO:%.*]] = add nsw <3 x i8> [[X:%.*]], <i8 poison, i8 2, i8 3>
; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x i8> [[BO]], <3 x i8> poison, <3 x i32> <i32 1, i32 undef, i32 2>
; CHECK-NEXT: ret <3 x i8> [[R]]
;
define <3 x i8> @shuf_sub(<3 x i8> %x) {
; CHECK-LABEL: @shuf_sub(
-; CHECK-NEXT: [[BO:%.*]] = sub <3 x i8> <i8 1, i8 poison, i8 3>, [[X:%.*]]
+; CHECK-NEXT: [[BO:%.*]] = sub nuw <3 x i8> <i8 1, i8 poison, i8 3>, [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x i8> [[BO]], <3 x i8> poison, <3 x i32> <i32 0, i32 undef, i32 2>
; CHECK-NEXT: ret <3 x i8> [[R]]
;
define <3 x i8> @shuf_mul(<3 x i8> %x) {
; CHECK-LABEL: @shuf_mul(
-; CHECK-NEXT: [[BO:%.*]] = mul <3 x i8> [[X:%.*]], <i8 1, i8 poison, i8 3>
+; CHECK-NEXT: [[BO:%.*]] = mul nsw <3 x i8> [[X:%.*]], <i8 1, i8 poison, i8 3>
; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x i8> [[BO]], <3 x i8> poison, <3 x i32> <i32 0, i32 2, i32 0>
; CHECK-NEXT: ret <3 x i8> [[R]]
;
define <3 x i8> @shuf_add(<3 x i8> %x) {
; CHECK-LABEL: @shuf_add(
-; CHECK-NEXT: [[BO:%.*]] = add <3 x i8> [[X:%.*]], <i8 poison, i8 2, i8 3>
+; CHECK-NEXT: [[BO:%.*]] = add nsw <3 x i8> [[X:%.*]], <i8 poison, i8 2, i8 3>
; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x i8> [[BO]], <3 x i8> undef, <3 x i32> <i32 1, i32 undef, i32 2>
; CHECK-NEXT: ret <3 x i8> [[R]]
;
define <3 x i8> @shuf_sub(<3 x i8> %x) {
; CHECK-LABEL: @shuf_sub(
-; CHECK-NEXT: [[BO:%.*]] = sub <3 x i8> <i8 1, i8 poison, i8 3>, [[X:%.*]]
+; CHECK-NEXT: [[BO:%.*]] = sub nuw <3 x i8> <i8 1, i8 poison, i8 3>, [[X:%.*]]
; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x i8> [[BO]], <3 x i8> undef, <3 x i32> <i32 0, i32 undef, i32 2>
; CHECK-NEXT: ret <3 x i8> [[R]]
;
define <3 x i8> @shuf_mul(<3 x i8> %x) {
; CHECK-LABEL: @shuf_mul(
-; CHECK-NEXT: [[BO:%.*]] = mul <3 x i8> [[X:%.*]], <i8 1, i8 poison, i8 3>
+; CHECK-NEXT: [[BO:%.*]] = mul nsw <3 x i8> [[X:%.*]], <i8 1, i8 poison, i8 3>
; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x i8> [[BO]], <3 x i8> undef, <3 x i32> <i32 0, i32 2, i32 0>
; CHECK-NEXT: ret <3 x i8> [[R]]
;