Open
Description
Test code
#include <stdint.h>
extern void subroutine(uint64_t x);
void func1(int32_t a, int32_t b) {
if (a > b)
return;
subroutine(b - a);
}
void func2(int32_t a, int32_t b) {
if (a > b)
return;
subroutine((uint64_t)(int32_t)(b - a));
}
void func3(int32_t a, int32_t b) {
if (a > b)
return;
subroutine((uint64_t)(uint32_t)(b - a));
}
uint64_t func4(int32_t a, int32_t b) {
if (a > b)
return 0;
return (b - a);
}
uint64_t func5(int32_t a, int32_t b) {
if (a > b)
return 0;
return (uint64_t)(int32_t)(b - a);
}
uint64_t func6(int32_t a, int32_t b) {
if (a > b)
return 0;
return (uint64_t)(uint32_t)(b - a);
}
Actual result (x86-64 clang 20.1.0 with -Os
option): func1
, func2
, func4
and func5
made unnecessary sign extensions (movsxd
instruction). (https://godbolt.org/z/s3zvnET5e)
Expected result: func1
, func2
and func3
compile to same code. func4
, func5
and func6
compile to same code.
After the (a > b)
conditional, Clang should be able to know that (a <= b)
, which in turn implies (0 <= b - a)
. In other words, (b - a)
would be always nonnegative.