@@ -5,6 +5,7 @@ target datalayout = "n64"
55
66declare void @use1 (i1 )
77declare void @use32 (i32 )
8+ declare void @use64 (i64 )
89declare void @use_vec (<2 x i9 >)
910
1011define i64 @test_sext_zext (i16 %A ) {
@@ -777,3 +778,66 @@ define i64 @evaluate_zexted_const_expr(i1 %c) {
777778 %ext = zext i7 %and to i64
778779 ret i64 %ext
779780}
781+
782+ ; FIXME: This is currently miscompiling as the and gets dropped,
783+ ; but the flag on the zext doesn't.
784+ define i16 @zext_nneg_flag_drop (i8 %x , i16 %y ) {
785+ ; CHECK-LABEL: @zext_nneg_flag_drop(
786+ ; CHECK-NEXT: [[EXT:%.*]] = zext nneg i8 [[X:%.*]] to i16
787+ ; CHECK-NEXT: [[OR1:%.*]] = or i16 [[EXT]], [[Y:%.*]]
788+ ; CHECK-NEXT: [[OR2:%.*]] = or i16 [[OR1]], 128
789+ ; CHECK-NEXT: ret i16 [[OR2]]
790+ ;
791+ %and = and i8 %x , 127
792+ %ext = zext nneg i8 %and to i16
793+ %or1 = or i16 %ext , %y
794+ %or2 = or i16 %or1 , 128
795+ ret i16 %or2
796+ }
797+
798+ define i32 @zext_nneg_redundant_and (i8 %a ) {
799+ ; CHECK-LABEL: @zext_nneg_redundant_and(
800+ ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A:%.*]], 127
801+ ; CHECK-NEXT: [[RES:%.*]] = zext i8 [[TMP1]] to i32
802+ ; CHECK-NEXT: ret i32 [[RES]]
803+ ;
804+ %a.i32 = zext nneg i8 %a to i32
805+ %res = and i32 %a.i32 , 127
806+ ret i32 %res
807+ }
808+
809+ ; Negative test, the and can't be removed
810+ define i32 @zext_nneg_redundant_and_neg (i8 %a ) {
811+ ; CHECK-LABEL: @zext_nneg_redundant_and_neg(
812+ ; CHECK-NEXT: [[B:%.*]] = and i8 [[A:%.*]], 127
813+ ; CHECK-NEXT: [[B_I32:%.*]] = zext nneg i8 [[B]] to i32
814+ ; CHECK-NEXT: ret i32 [[B_I32]]
815+ ;
816+ %b = and i8 %a , 127
817+ %b.i32 = zext nneg i8 %b to i32
818+ ret i32 %b.i32
819+ }
820+
821+ define i64 @zext_nneg_signbit_extract (i32 %a ) nounwind {
822+ ; CHECK-LABEL: @zext_nneg_signbit_extract(
823+ ; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[A:%.*]], 31
824+ ; CHECK-NEXT: [[C:%.*]] = zext i32 [[TMP1]] to i64
825+ ; CHECK-NEXT: ret i64 [[C]]
826+ ;
827+ %b = zext nneg i32 %a to i64
828+ %c = lshr i64 %b , 31
829+ ret i64 %c
830+ }
831+
832+ define i64 @zext_nneg_demanded_constant (i8 %a ) nounwind {
833+ ; CHECK-LABEL: @zext_nneg_demanded_constant(
834+ ; CHECK-NEXT: [[B:%.*]] = zext nneg i8 [[A:%.*]] to i64
835+ ; CHECK-NEXT: call void @use64(i64 [[B]]) #[[ATTR0:[0-9]+]]
836+ ; CHECK-NEXT: [[C:%.*]] = and i64 [[B]], 254
837+ ; CHECK-NEXT: ret i64 [[C]]
838+ ;
839+ %b = zext nneg i8 %a to i64
840+ call void @use64 (i64 %b )
841+ %c = and i64 %b , 254
842+ ret i64 %c
843+ }
0 commit comments