cb424d7448
verify-patch-sanity.py validates every active recipe .patch has internally- consistent hunk line counts — catching the 'malformed patch at line N' failure at commit/CI/preflight time instead of hours into a cook. This cycle hit that class three times (qtwaylandscanner, sddm, xwayland), each only discovered when cookbook tried to apply the patch. Running it across the repo found 29 latent malformed patches (validated against GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22'). They were harmless only because they sit in vendored recipes (baked, not re- applied) — but would fail on any version-bump re-derivation. --fix recounts the hunk headers (body untouched) and repaired all 29. Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test (test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats (empty placeholders, bare-@@ git hunks).
132 lines
4.7 KiB
C
132 lines
4.7 KiB
C
// REQUIRES: x86-registered-target
|
|
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -O0 -emit-llvm %s -o - | FileCheck %s
|
|
// RUN: %clang_cc1 -triple i386-pc-linux-gnu -O0 -emit-llvm %s -o - | FileCheck %s
|
|
|
|
int test1(int cond) {
|
|
// CHECK-LABEL: define{{.*}} i32 @test1(
|
|
// CHECK: callbr void asm sideeffect
|
|
// CHECK: to label %asm.fallthrough [label %label_true, label %loop]
|
|
// CHECK-LABEL: asm.fallthrough:
|
|
asm volatile goto("testl %0, %0; jne %l1;" :: "r"(cond)::label_true, loop);
|
|
asm volatile goto("testl %0, %0; jne %l2;" :: "r"(cond)::label_true, loop);
|
|
// CHECK: callbr void asm sideeffect
|
|
// CHECK: to label %asm.fallthrough1 [label %label_true, label %loop]
|
|
// CHECK-LABEL: asm.fallthrough1:
|
|
return 0;
|
|
loop:
|
|
return 0;
|
|
label_true:
|
|
return 1;
|
|
}
|
|
|
|
int test2(int cond) {
|
|
// CHECK-LABEL: define{{.*}} i32 @test2(
|
|
// CHECK: callbr i32 asm sideeffect
|
|
// CHECK: to label %asm.fallthrough [label %label_true.split, label %loop.split]
|
|
// CHECK-LABEL: asm.fallthrough:
|
|
asm volatile goto("testl %0, %0; jne %l2;" : "=r"(cond) : "r"(cond) :: label_true, loop);
|
|
asm volatile goto("testl %0, %0; jne %l3;" : "=r"(cond) : "r"(cond) :: label_true, loop);
|
|
// CHECK: callbr i32 asm sideeffect
|
|
// CHECK: to label %asm.fallthrough1 [label %label_true.split2, label %loop.split3]
|
|
// CHECK-LABEL: asm.fallthrough1:
|
|
return 0;
|
|
loop:
|
|
return 0;
|
|
label_true:
|
|
return 1;
|
|
}
|
|
|
|
int test3(int out1, int out2) {
|
|
// CHECK-LABEL: define{{.*}} i32 @test3(
|
|
// CHECK: callbr { i32, i32 } asm sideeffect
|
|
// CHECK: to label %asm.fallthrough [label %label_true.split, label %loop.split]
|
|
// CHECK-LABEL: asm.fallthrough:
|
|
asm volatile goto("testl %0, %0; jne %l3;" : "=r"(out1), "=r"(out2) : "r"(out1) :: label_true, loop);
|
|
asm volatile goto("testl %0, %0; jne %l4;" : "=r"(out1), "=r"(out2) : "r"(out1) :: label_true, loop);
|
|
// CHECK: callbr { i32, i32 } asm sideeffect
|
|
// CHECK: to label %asm.fallthrough6 [label %label_true.split11, label %loop.split14]
|
|
// CHECK-LABEL: asm.fallthrough6:
|
|
return 0;
|
|
loop:
|
|
return 0;
|
|
label_true:
|
|
return 1;
|
|
}
|
|
|
|
int test4(int out1, int out2) {
|
|
// CHECK-LABEL: define{{.*}} i32 @test4(
|
|
// CHECK: callbr { i32, i32 } asm sideeffect "jne ${5:l}", "={si},={di},r,0,1,!i,!i
|
|
// CHECK: to label %asm.fallthrough [label %label_true.split, label %loop.split]
|
|
// CHECK-LABEL: asm.fallthrough:
|
|
if (out1 < out2)
|
|
asm volatile goto("jne %l5" : "+S"(out1), "+D"(out2) : "r"(out1) :: label_true, loop);
|
|
else
|
|
asm volatile goto("jne %l7" : "+S"(out1), "+D"(out2) : "r"(out1), "r"(out2) :: label_true, loop);
|
|
// CHECK: callbr { i32, i32 } asm sideeffect "jne ${7:l}", "={si},={di},r,r,0,1,!i,!i
|
|
// CHECK: to label %asm.fallthrough6 [label %label_true.split11, label %loop.split14]
|
|
// CHECK-LABEL: asm.fallthrough6:
|
|
return out1 + out2;
|
|
loop:
|
|
return -1;
|
|
label_true:
|
|
return -2;
|
|
}
|
|
|
|
int test5(int addr, int size, int limit) {
|
|
// CHECK-LABEL: define{{.*}} i32 @test5(
|
|
// CHECK: callbr i32 asm "add $1,$0 ; jc ${4:l} ; cmp $2,$0 ; ja ${4:l} ; ", "=r,imr,imr,0,!i
|
|
// CHECK: to label %asm.fallthrough [label %t_err.split]
|
|
// CHECK-LABEL: asm.fallthrough:
|
|
asm goto(
|
|
"add %1,%0 ; "
|
|
"jc %l[t_err] ; "
|
|
"cmp %2,%0 ; "
|
|
"ja %l[t_err] ; "
|
|
: "+r" (addr)
|
|
: "g" (size), "g" (limit)
|
|
: : t_err);
|
|
return 0;
|
|
t_err:
|
|
return 1;
|
|
}
|
|
|
|
int test6(int out1) {
|
|
// CHECK-LABEL: define{{.*}} i32 @test6(
|
|
// CHECK: callbr i32 asm sideeffect "testl $0, $0; testl $1, $1; jne ${3:l}", "={si},r,0,!i,!i,{{.*}}
|
|
// CHECK: to label %asm.fallthrough [label %label_true.split, label %landing.split]
|
|
// CHECK-LABEL: asm.fallthrough:
|
|
// CHECK-LABEL: landing:
|
|
int out2 = 42;
|
|
asm volatile goto("testl %0, %0; testl %1, %1; jne %l3" : "+S"(out2) : "r"(out1) :: label_true, landing);
|
|
landing:
|
|
return out1 + out2;
|
|
label_true:
|
|
return -2;
|
|
}
|
|
|
|
// test7 - For the output templates in the asm string (%0, %l2), GCC places
|
|
// hidden inputs tied to outputs ("+r" constraint) BEFORE labels. Test that foo
|
|
// is $2 (or rather ${2:l} because of the l output template) in the emitted asm
|
|
// string, not $1.
|
|
void *test7(void) {
|
|
// CHECK-LABEL: define{{.*}} ptr @test7(
|
|
// CHECK: %1 = callbr ptr asm "# $0\0A\09# ${2:l}", "=r,0,!i,~{dirflag},~{fpsr},~{flags}"(ptr %0)
|
|
// CHECK-NEXT: to label %asm.fallthrough [label %foo.split]
|
|
void *p = &&foo;
|
|
asm goto ("# %0\n\t# %l2":"+r"(p):::foo);
|
|
foo:
|
|
return p;
|
|
}
|
|
|
|
// test8 - the same as test7, but this time we use symbolic names rather than
|
|
// numbered outputs.
|
|
void *test8(void) {
|
|
// CHECK-LABEL: define{{.*}} ptr @test8(
|
|
// CHECK: %1 = callbr ptr asm "# $0\0A\09# ${2:l}", "=r,0,!i,~{dirflag},~{fpsr},~{flags}"(ptr %0)
|
|
// CHECK-NEXT: to label %asm.fallthrough [label %foo.split]
|
|
void *p = &&foo;
|
|
asm goto ("# %0\n\t# %l[foo]":"+r"(p):::foo);
|
|
foo:
|
|
return p;
|
|
}
|