; RUN: llc -mtriple=thumbv8m.main -mcpu=cortex-m33 %s -arm-disable-cgp=false -o - | FileCheck %s ; CHECK: overflow_add ; CHECK: add ; CHECK: uxth ; CHECK: cmp define zeroext i16 @overflow_add(i16 zeroext %a, i16 zeroext %b) { %add = add i16 %a, %b %or = or i16 %add, 1 %cmp = icmp ugt i16 %or, 1024 %res = select i1 %cmp, i16 2, i16 5 ret i16 %res } ; CHECK-LABEL: overflow_sub ; CHECK: sub ; CHECK: uxth ; CHECK: cmp define zeroext i16 @overflow_sub(i16 zeroext %a, i16 zeroext %b) { %add = sub i16 %a, %b %or = or i16 %add, 1 %cmp = icmp ugt i16 %or, 1024 %res = select i1 %cmp, i16 2, i16 5 ret i16 %res } ; CHECK-LABEL: overflow_mul ; CHECK: mul ; CHECK: uxth ; CHECK: cmp define zeroext i16 @overflow_mul(i16 zeroext %a, i16 zeroext %b) { %add = mul i16 %a, %b %or = or i16 %add, 1 %cmp = icmp ugt i16 %or, 1024 %res = select i1 %cmp, i16 2, i16 5 ret i16 %res } ; CHECK-LABEL: overflow_shl ; CHECK-COMMON: lsl ; CHECK-COMMON: uxth ; CHECK-COMMON: cmp define zeroext i16 @overflow_shl(i16 zeroext %a, i16 zeroext %b) { %add = shl i16 %a, %b %or = or i16 %add, 1 %cmp = icmp ugt i16 %or, 1024 %res = select i1 %cmp, i16 2, i16 5 ret i16 %res } ; CHECK-LABEL: overflow_add_no_consts: ; CHECK: add r0, r1 ; CHECK: uxtb [[EXT:r[0-9]+]], r0 ; CHECK: cmp [[EXT]], r2 ; CHECK: movhi r0, #8 define i32 @overflow_add_no_consts(i8 zeroext %a, i8 zeroext %b, i8 zeroext %limit) { %add = add i8 %a, %b %cmp = icmp ugt i8 %add, %limit %res = select i1 %cmp, i32 8, i32 16 ret i32 %res } ; CHECK-LABEL: overflow_add_const_limit: ; CHECK: add r0, r1 ; CHECK: uxtb [[EXT:r[0-9]+]], r0 ; CHECK: cmp [[EXT]], #128 ; CHECK: movhi r0, #8 define i32 @overflow_add_const_limit(i8 zeroext %a, i8 zeroext %b) { %add = add i8 %a, %b %cmp = icmp ugt i8 %add, 128 %res = select i1 %cmp, i32 8, i32 16 ret i32 %res } ; CHECK-LABEL: overflow_add_positive_const_limit: ; CHECK: adds r0, #1 ; CHECK: uxtb [[EXT:r[0-9]+]], r0 ; CHECK: cmp [[EXT]], #128 ; CHECK: movhi r0, #8 define i32 @overflow_add_positive_const_limit(i8 zeroext %a) { %add = add i8 %a, 1 %cmp = icmp ugt i8 %add, 128 %res = select i1 %cmp, i32 8, i32 16 ret i32 %res } ; CHECK-LABEL: unsafe_add_underflow: ; CHECK: subs r0, #2 ; CHECK: uxtb [[EXT:r[0-9]+]], r0 ; CHECK: cmp [[EXT]], #255 ; CHECK: moveq r0, #8 define i32 @unsafe_add_underflow(i8 zeroext %a) { %add = add i8 %a, -2 %cmp = icmp ugt i8 %add, 254 %res = select i1 %cmp, i32 8, i32 16 ret i32 %res } ; CHECK-LABEL: safe_add_underflow: ; CHECK: subs [[MINUS_1:r[0-9]+]], r0, #1 ; CHECK-NOT: uxtb ; CHECK: cmp [[MINUS_1]], #254 ; CHECK: movhi r0, #8 define i32 @safe_add_underflow(i8 zeroext %a) { %add = add i8 %a, -1 %cmp = icmp ugt i8 %add, 254 %res = select i1 %cmp, i32 8, i32 16 ret i32 %res } ; CHECK-LABEL: safe_add_underflow_neg: ; CHECK: subs [[MINUS_1:r[0-9]+]], r0, #2 ; CHECK-NOT: uxtb ; CHECK: cmp [[MINUS_1]], #251 ; CHECK: movlo r0, #8 define i32 @safe_add_underflow_neg(i8 zeroext %a) { %add = add i8 %a, -2 %cmp = icmp ule i8 %add, -6 %res = select i1 %cmp, i32 8, i32 16 ret i32 %res } ; CHECK-LABEL: overflow_sub_negative_const_limit: ; CHECK: adds r0, #1 ; CHECK: uxtb [[EXT:r[0-9]+]], r0 ; CHECK: cmp [[EXT]], #128 ; CHECK: movhi r0, #8 define i32 @overflow_sub_negative_const_limit(i8 zeroext %a) { %sub = sub i8 %a, -1 %cmp = icmp ugt i8 %sub, 128 %res = select i1 %cmp, i32 8, i32 16 ret i32 %res } ; CHECK-LABEL: unsafe_sub_underflow: ; CHECK: subs r0, #6 ; CHECK: uxtb [[EXT:r[0-9]+]], r0 ; CHECK: cmp [[EXT]], #250 ; CHECK: movhi r0, #8 define i32 @unsafe_sub_underflow(i8 zeroext %a) { %sub = sub i8 %a, 6 %cmp = icmp ugt i8 %sub, 250 %res = select i1 %cmp, i32 8, i32 16 ret i32 %res } ; CHECK-LABEL: safe_sub_underflow: ; CHECK: subs [[MINUS_1:r[0-9]+]], r0, #1 ; CHECK-NOT: uxtb ; CHECK: cmp [[MINUS_1]], #255 ; CHECK: movlo r0, #8 define i32 @safe_sub_underflow(i8 zeroext %a) { %sub = sub i8 %a, 1 %cmp = icmp ule i8 %sub, 254 %res = select i1 %cmp, i32 8, i32 16 ret i32 %res } ; CHECK-LABEL: safe_sub_underflow_neg ; CHECK: subs [[MINUS_1:r[0-9]+]], r0, #4 ; CHECK-NOT: uxtb ; CHECK: cmp [[MINUS_1]], #250 ; CHECK: movhi r0, #8 define i32 @safe_sub_underflow_neg(i8 zeroext %a) { %sub = sub i8 %a, 4 %cmp = icmp uge i8 %sub, -5 %res = select i1 %cmp, i32 8, i32 16 ret i32 %res } ; CHECK: subs r0, #4 ; CHECK: uxtb [[EXT:r[0-9]+]], r0 ; CHECK: cmp [[EXT]], #253 ; CHECK: movlo r0, #8 define i32 @unsafe_sub_underflow_neg(i8 zeroext %a) { %sub = sub i8 %a, 4 %cmp = icmp ult i8 %sub, -3 %res = select i1 %cmp, i32 8, i32 16 ret i32 %res }